Why does Python requests ignore the verify parameter?
Solution 1:
Certificate validation did not fail, so the verify
argument doesn't apply here. What failed is the cipher negotiation; none of the ciphers requests
is willing to use match those the server is willing to use.
If you run your curl
command with the -v
switch you'll see what cipher suite was negotiated by curl
for the successful connection:
$ curl -v -I https://service.isracard.co.il/I_logon.jsp
* Hostname was NOT found in DNS cache
* Trying 192.118.12.8...
* Connected to service.isracard.co.il (192.118.12.8) port 443 (#0)
* TLS 1.2 connection using TLS_RSA_WITH_RC4_128_SHA
[ .... ]
That's the RC4-SHA cipher, which has some rather troublesome securty issues and should not really be used; it offers no forward secrecy for example. The urllib3
package (bundled with requests
) by default excludes that cipher from the default ciphers. You can add it back with:
import requests
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':RC4-SHA'
try:
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST += ':RC4-SHA'
except AttributeError:
# no pyopenssl support used / needed / available
pass
and your request works:
>>> import requests
>>> requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':RC4-SHA'
>>> requests.get('https://service.isracard.co.il/I_logon.jsp')
<Response [200]>
I didn't install the pyOpenSSL package so I didn't bother with the try..except
guarded part.
Solution 2:
I run into this as well on macOS Sierra, Python 2.7.9 and it is fixed by:
sudo pip install --ignore-installed pyOpenSSL --upgrade
It's probably due to the pyOpenSSL is too old.