python 请求 ssl 握手失败

python requests ssl handshake failure

每次我尝试做:

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

我收到这条消息:

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

我什么都试过了:

但没有任何变化。

我正在使用 Python 2.7.6,无法更改。

I am using python 2.7.6 cant change it.

那么对不起你。您尝试访问的服务器需要 (SNI) Server Name Indication,如果客户端未使用此 SNI 扩展,将导致握手失败。对 SNI 的支持仅在 python 2.7.9 中添加,所以它看起来像您运气不好。

我最终解决了问题 我将我的 ubuntu 从 14.04 更新到 14.10,问题解决了

但在 ubuntu 和 python 的旧版本中,我安装了这些库,它似乎解决了我所有的问题

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

如果您没有安装 pip2.7,您可以改用 pip

如果您无法将 Python 版本升级到 2.7.9,则将请求包降级到 2.5.3。这对我有用。

sudo pip install requests==2.5.3

编辑

您还可以安装带有安全扩展的请求

pip install requests[security]

在 OSX 上,使用 python 2.7.10 / 请求 2.9.1 我只需要安装 requests 使用其安全设置:

pip install requests[security]

这会安装 pyOpenSSLndg-httpsclientpyasn1https://github.com/kennethreitz/requests/blob/master/setup.py#L70

您只需要升级您的请求。

pip 安装请求 --upgrade

您仍然可以使用 python 2.7.

在尝试了上述所有解决方案并陷入困境之后,最终破获此​​案的是简单地尝试从 urllib3 包中导入 pyopenssl,如下所示:

from urllib3.contrib import pyopenssl

这导致我犯了错误(缺少 cryptography 包)

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()

我在使用过时的 HTTPS 连接到旧网站时不断收到此错误消息。

最后我不得不使用适配器手动设置协议和密码才能使请求正常工作。

对我有用的 -

  1. 转到像这样的诊断站点 https://www.ssllabs.com/ssltest/analyze.html
  2. 找出网站使用的协议(TLS1.0、TLS1.2、SSL3.0(仅?)....)
  3. 找出使用了哪些过时的密码套件
  4. 从 3) 将密码名称转换为列表中的 openssl 名称,如 https://www.openssl.org/docs/man1.1.0/apps/ciphers.html or http://testssl.sh/openssl-rfc.mapping.html 以在代码中使用

然后在请求中使用您在上面研究的内容创建一个适配器

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)

现在我将适配器挂载到请求对象

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

运行 python 2.7.13。我在这里尝试了推荐的解决方案,最终安装了以下内容:

  • pip install requests[security](已安装 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)

没有帮助,然后尝试

  • pip install -U requests(已安装 certifi-2018.10.15 chardet-3.0.4 requests-2.20.1 urllib3-1.24.1)

没有帮助。终于试过了

  • pip install -U httplib2 (httplib2-0.12.0)

解决了问题。之前我是运行 httplib2==0.9.2