python请求ssl握手失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31649390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 10:21:08  来源:igfitidea点击:

python requests ssl handshake failure

pythonpython-requests

提问by Idan Haim Shalom

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
  • 更新我的请求
  • 更新我的 ssl

but nothing changes.

但没有任何变化。

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

我使用的是 Python 2.7.6,无法更改。

采纳答案by Idan Haim Shalom

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

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

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

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

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

如果你没有安装 pip2.7 你可以使用 pip 代替

回答by Steffen Ullrich

I am using python 2.7.6 cant change it.

我正在使用 python 2.7.6 无法更改它。

Sorry for you then. The server you are trying to reach requires (SNI) Server Name Indicationand 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.

那就对不起你了。您尝试访问的服务器需要(SNI) 服务器名称指示,并且如果客户端未使用此 SNI 扩展,则会导致握手失败。仅在 python 2.7.9 中添加了对 SNI 的支持,因此看起来您已经不在运气。

回答by Hassan Raza

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.

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

sudo pip install requests==2.5.3

Edit

编辑

You can also install requests with security extension

您还可以使用安全扩展安装请求

pip install requests[security]

回答by Tobias Lorenz

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

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

pip install requests[security]

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

这将安装pyOpenSSL,ndg-httpsclientpyasn1. https://github.com/kennethreitz/requests/blob/master/setup.py#L70

回答by Jenny Jane

You just need to upgrade your requests.

您只需要升级您的请求。

pip install requests --upgrade

pip 安装请求 --upgrade

You can still use python 2.7.

您仍然可以使用 python 2.7。

回答by Bobby

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:

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

from urllib3.contrib import pyopenssl

from urllib3.contrib import pyopenssl

which led me right to the error (missing the cryptographypackage)

这导致我正确的错误(缺少cryptography包裹)

回答by Amr

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

回答by uosjead

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

使用过时的 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.htmlor http://testssl.sh/openssl-rfc.mapping.htmlto use in code
  1. 转到这样的诊断站点https://www.ssllabs.com/ssltest/analyze.html
  2. 找出网站使用的协议(TLS1.0、TLS1.2、SSL3.0(仅?)....)
  3. 找出使用了哪些过时的密码套件
  4. 从 3) 将密码名称转换为https://www.openssl.org/docs/man1.1.0/apps/ciphers.htmlhttp://testssl.sh/openssl-rfc.mapping等列表中的 openssl 名称.html在代码中使用

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...

回答by Lou K

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

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

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

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)
  • pip install -U requests(已安装 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)
  • pip install -U httplib2(httplib2-0.12.0)

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

这解决了问题。以前我运行的是 httplib2==0.9.2