I want to make a routine for a client that has Python 2.7.5 installed, the routine must consume a much newer API, but I get the following error:
"requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure"
It is related to SSL/TLS compatibility issues, but I don't know how to skip it. Although the question is if you can jump in that version of Python?
class http_Factory:
def __init__(self):
# Lee la configuración desde appsettings.json
self.app_settings= AppConfig.get_proxy_config()
self.proxy_url = self.app_settings.get('Url')
self.proxy_user = self.app_settings.get('Username')
self.proxy_password = self.app_settings.get('Password')
# Configura las cabeceras (headers) comunes
def make_request(self, url, method=None, params=None, data=None, headers=None):
if data is not None:
# Convierte el diccionario a JSON si hay datos
data = json.dumps(data)
if self.proxy_url and self.proxy_user and self.proxy_password:
# Usa un proxy si se proporcionan las configuraciones
proxies = {
'http': 'http://{}'.format(self.proxy_url),
'https': 'https://{}'.format(self.proxy_url),
}
auth = HTTPProxyAuth(self.proxy_user, self.proxy_password)
response = requests.request(method, url, params=params, data=data, proxies=proxies, auth=auth, headers=headers)
else:
# Sin proxy
response = requests.request(method, url, params=params, data=data, headers=headers, verify= False)
return response
The success of the SSL connection depends on both the OpenSSL version and the Python version (i.e. the
_sslextension module bundled with Python). Trying to upgrade any of these may fix the issue. Alternatively, changing some configuration option such as the allowed protocols and ciphers may fix the issue.If your client insists on using Python 2.7, here are the options I see for upgrading:
Upgrade to Python 2.7.18, which is the latest Python version from the 2.7 series. Depending on the distribution, it may contain a newer version of OpenSSL 1.0 or 1.1 than the Python 2.7.5 your client is currently using. Also the bundled
_sslextension module is definitely newer, which can also help.Upgrade OpenSSL to the latest 1.1.1 (currently 1.1.1w). This also involves building Python from source, because its
_sslextension module needs to be linked to the upgraded OpenSSL. This can still work with Python 2.7.5 (when rebuilt from source), and also with Python 2.7.18. I'd try both. The first few search results may be useful:The underlying reasons are the following:
Secure communication over TCP (e.g. https://, imaps:) is done via various versions of the SSL or TLS protocols. The client and server can negotiate a protocol and a version at connection time, i.e. they can agree on one which they are both happy with. (Except when their configured allowed protocol--version pairs are disjoint.)
Various cryptographic algorithms with various parameters are used during setup and transfer. One of those is the symmetric cipher, which is used to encrypt all transfer traffic. Other algorithms are used during setup, e.g. to verify the identity of the server and to generate and communicate the symmetric cipher key. This can also work, if the configured algorithm--parameter pairs on the client and the server are disjoint.
There are various software libraries for secure communication (such as OpenSSL, LibreSSL, BoringSSL, Go's own implementation) which support various features (protocols, versions, algorithms and parameters). Some of those features are disabled at compile time or configuration time. Different versions of the libraries support different features.
Python (2.x and 3.x) uses OpenSSL as the secure communication library, with some extra code in the
_sslextension module, part of the CPython source code. The features supported by_sslare a subset of those supported by OpenSSL. Thus to make a specific connection working, both_ssland OpenSSL need to have the correct features, and these features have to be enabled both at compile time and in the configuration.The OpenSSL error message in the Python exception text (e.g. error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure) is not verbose enough to indicate which features have to be enabled to make it work.
One important reason why some features are disabled by default is that it was discovered later that they are insecure. The client doesn't have control over what features are enabled on the server (and also the other way round). The most secure way to make a connection work is upgrading both the client and the server, given that the library defaults are trusted.