I need to get data from a URL that has some certificate problems. It works with curl -k
(that skips verification). So I tried with verify=False
in python requests
but I'm still getting [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE]. Any idea how to bypass this?
I'm using python 3.10.12 and requests 2.32.3 Here goes a code for testing purposes:
import os
import requests
# curl fails
teste = os.system("curl -o capabilities.xml ';version=1.3.0&request=GetCapabilities'")
# ignoring verification -k works
teste = os.system("curl -k -o capabilities.xml ';version=1.3.0&request=GetCapabilities'")
# Trying with python
url = ";
params = {
'service':'WMS',
'version':'1.3.0',
'request':'GetCapabilities'
}
# this fails with certificate error
teste = requests.get(url, params)
# verify = False does not do the trick
teste = requests.get(url, params, verify=False)
Update:
It appears as though the site uses only TLS1.2 for cypher suit and python requests does not like that. Any way to have python use that Cypher?
I need to get data from a URL that has some certificate problems. It works with curl -k
(that skips verification). So I tried with verify=False
in python requests
but I'm still getting [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE]. Any idea how to bypass this?
I'm using python 3.10.12 and requests 2.32.3 Here goes a code for testing purposes:
import os
import requests
# curl fails
teste = os.system("curl -o capabilities.xml 'https://geoserver.car.gov.br/geoserver/ows?service=WMS&version=1.3.0&request=GetCapabilities'")
# ignoring verification -k works
teste = os.system("curl -k -o capabilities.xml 'https://geoserver.car.gov.br/geoserver/ows?service=WMS&version=1.3.0&request=GetCapabilities'")
# Trying with python
url = "https://geoserver.car.gov.br/geoserver/ows"
params = {
'service':'WMS',
'version':'1.3.0',
'request':'GetCapabilities'
}
# this fails with certificate error
teste = requests.get(url, params)
# verify = False does not do the trick
teste = requests.get(url, params, verify=False)
Update:
It appears as though the site uses only TLS1.2 for cypher suit and python requests does not like that. Any way to have python use that Cypher?
Share Improve this question edited Mar 17 at 13:29 Daniel asked Mar 17 at 13:11 DanielDaniel 6301 gold badge5 silver badges15 bronze badges 1- If your OpenSSL version is "old enough" (pre March 2020), apparently it can be done by lowering the minimal required protocol version, reddit/r/learnpython/comments/hw6ann/comment/fyzh0ex If that's not an option/doesn't work for you, you might need something like this, I'm guessing? lukasa.co.uk/2017/02/Configuring_TLS_With_Requests – C3roe Commented Mar 17 at 13:36
1 Answer
Reset to default 0The problem is not the TLS version, TLS 1.2 is still allowed by default in current Python. The problem is instead that the server only supports weak ciphers which require the obsolete RSA key exchange (i.e. no forward secrecy). To allow this you need to adjust the security level:
import requests
import ssl
from requests.adapters import HTTPAdapter
class CustomSSLAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
ssl_context = ssl.create_default_context()
ssl_context.set_ciphers('DEFAULT@SECLEVEL=0')
ssl_context.check_hostname = False
kwargs["ssl_context"] = ssl_context
return super().init_poolmanager(*args, **kwargs)
sess = requests.Session()
sess.mount('https://', CustomSSLAdapter())
url = 'https://geoserver.car.gov.br/geoserver/ows?service=WMS&version=1.3.0&request=GetCapabilities'
resp = sess.get(url, verify=False)
print(resp)