python requests ssl handshake failure

Question:

Every time I try to do:

requests.get('https://url') 

I got this message:

import requests
>>> requests.get('https://reviews.gethuman.com/companies') 
Traceback (most recent call last): 
   File "<stdin>", line 1, in <module> 
   File "/usr/lib/python2.7/dist-packages/requests/api.py", line 55, in get 
    return request('get', url, **kwargs) 
   File "/usr/lib/python2.7/dist-packages/requests/api.py", line 44, in request 
    return session.request(method=method, url=url, **kwargs)    
   File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 455, in request 
    resp = self.send(prep, **send_kwargs) 
   File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 558, in send 
    r = adapter.send(request, **kwargs) 
   File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 385, in send 
    raise SSLError(e) requests.exceptions.SSLError: [Errno 1]
_ssl.c:510: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

I tried everything:

  • update my requests
  • update my ssl

but nothing changes.

I am using Python 2.7.6, can’t change this.

Asked By: Idan Haim Shalom

||

Answers:

I am using python 2.7.6 cant change it.

Sorry for you then. The server you are trying to reach requires (SNI) Server Name Indication and will cause a handshake failure if the client is not using this SNI extension.. Support for SNI was only added with python 2.7.9 so it looks like you are out of luck.

Answered By: Steffen Ullrich

I resolve the problem in the end i updated my ubuntu from 14.04 to 14.10 and the problem was solved

but in the older version of ubuntu and python I install those lib and it seems to fix all my problems

sudo apt-get install python-dev libssl-dev libffi-dev
sudo pip2.7 install -U pyopenssl==0.13.1 pyasn1 ndg-httpsclient

if you don`t have pip2.7 installed you can use pip instead

Answered By: Idan Haim Shalom

If you are not able to upgrade your Python version to 2.7.9 then downgrade you requests package to 2.5.3. That worked for me.

sudo pip install requests==2.5.3

Edit

You can also install requests with security extension

pip install requests[security]
Answered By: Hassan Raza

On OSX, using python 2.7.10 / requests 2.9.1 I only had to to install requestsusing its security setup:

pip install requests[security]

This installs pyOpenSSL, ndg-httpsclient and pyasn1.
https://github.com/kennethreitz/requests/blob/master/setup.py#L70

Answered By: Tobias Lorenz

You just need to upgrade your requests.

pip install requests –upgrade

You can still use python 2.7.

Answered By: Jenny Jane

after trying all the above solutions and going down quite the rabbit hole, the thing that eventually cracked the case was simply trying to import pyopenssl from the urllib3 package like so:

from urllib3.contrib import pyopenssl

which led me right to the error (missing the cryptography package)

Answered By: Bobby
import requests

#Add support for all cipher suites
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS='ALL'
#Exclude use of pyopenssl (pyopenssl module may need to be installed first $pip install pyopenssl)
requests.packages.urllib3.contrib.pyopenssl.extract_from_urllib3()
Answered By: Amr

I kept getting this error message when connecting to an old website with obsolete HTTPS.

In the end I had to set the Protocol AND the Ciphers manually with an adapter for the request to work.

What worked for me –

  1. go to a diagnostics site like this one https://www.ssllabs.com/ssltest/analyze.html
  2. find out what protocol the website uses (TLS1.0, TLS1.2, SSL3.0 (only?) ….)
  3. find out what obsolete ciphers suite are used
  4. from 3) translate cipher name to the the openssl name from a list like https://www.openssl.org/docs/man1.1.0/apps/ciphers.html or http://testssl.sh/openssl-rfc.mapping.html to use in code

then in requests create an adapter with what you have researched above

import requests, ssl
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
from requests.packages.urllib3.util import ssl_

class OldInsecureWebsiteAdapter(HTTPAdapter):
    def __init__(self, **kwargs):
        super(OldInsecureWebsiteAdapter, self).__init__(**kwargs)
    def init_poolmanager(self, *pool_args, **pool_kwargs):
        """
        my website uses TLS1.0 ONLY (from step 2) 
        and several obsolete ciphers (from step 3/4 I only picked one)
        """
        context = ssl_.create_urllib3_context(ssl.PROTOCOL_TLSv1, ciphers="DES-CBC3-SHA")

        """
        website does not support anything else so exclude all other protocols
        """
        context.options |= ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_3 | ssl.OP_NO_TLSv1_2 
        context.options |= ssl.OP_NO_SSLv3 | ssl.OP_NO_SSLv2

        self.poolmanager = PoolManager(*pool_args,
                                   ssl_context=context,
                                   **pool_kwargs)

now I mount the adapter to the requests object

    url = "https://yourwebsite.gov.whocares"
    session = requests.session()
    session.mount(url, OldInsecureWebsiteAdapter())
    result = session.get(url) 
    #no more ssl3 handshake error...
Answered By: uosjead

Running python 2.7.13. I tried the recommended solutions here, which ended up installing the following:

  • pip install requests[security] (installed asn1crypto-0.24.0 cffi-1.11.5 cryptography-2.4.2 idna-2.7 ipaddress-1.0.22 ndg-httpsclient-0.5.1 pyOpenSSL-18.0.0 pyasn1-0.4.4 pycparser-2.19)

no help, then tried

  • pip install -U requests (installed certifi-2018.10.15 chardet-3.0.4 requests-2.20.1 urllib3-1.24.1)

no help. Finally tried

  • pip install -U httplib2 (httplib2-0.12.0)

which resolved the problem. Previously I was running httplib2==0.9.2

Answered By: Lou K
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.