编程语言
首页 > 编程语言> > Mavericks上python中的SSL证书验证失败

Mavericks上python中的SSL证书验证失败

作者:互联网

我陷入了持续的SSL验证问题.

SSL:CERTIFICATE_VERIFY_FAILED

我在构建让用户使用Mozilla Persona进行身份验证的Django应用程序时发现了错误.

(python3.4)> import requests
(python3.4)> requests.get('https://verifier.login.persona.org')

我得到一个SSL:CERTIFICATE_VERIFY_FAILED从对urllib3的请求追溯到ssl:

...
"/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/ssl.py", line 805, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)

...
"/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/requests-2.4.1-py3.4.egg/requests/packages/urllib3/connectionpool.py", line 543, in urlopen
    raise SSLError(e)
requests.packages.urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)

...
"/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/requests-2.4.1-py3.4.egg/requests/adapters.py", line 420, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)

python3和python2之间的区别

这就是它开始变得有趣的地方:使用python2.7时,我没有遇到相同的问题:

(python2.7)> import requests
(python2.7)> requests.get('https://verifier.login.persona.org')
<Response [200]>

我的第一个想法是两个版本的请求可能使用不同的证书[1],因此我很惊讶地发现两个文件完全相同:

(bash)$diff `python3.4 -c "import requests; print(requests.certs.where())"` \
             `python2.7 -c "import requests; print requests.certs.where()"`
# no diff

错误在openssl中重新创建并使用-CAFile解决

有趣的是,这个问题不仅限于python3.4 [2].

(bash)$openssl s_client -connect github.com:443
...
Verify return code: 20 (unable to get local issuer certificate)

编辑来自Steffen的评论告诉我,这种“调试”方法实际上没有提供信息,因为s_client期望使用-CApath进行验证.但是,我可以指定请求包正在使用的同一证书但没有得到相同的错误这一事实仍然很有趣:

(bash)$openssl s_client -connect github.com:443 \
        -CAfile `python3 -c 'import requests; print(requests.certs.where())'`
...
Verify return code: 0 (ok)

在这一点上,我完全不了解我的想法.我不知道这是否真的是一个opensl问题,或者是关于OSX Mavericks的问题[3].这是我正在使用的openssl版本:

(bash)$openssl version
OpenSSL 1.0.1f 6 Jan 2014

小牛KeyChain.app

对于特定于操作系统的解决方案,我尝试清除登录KeyChain [4],但无济于事.

点子问题

最后一点证据可能不相关. python3.4附带完整的pip.但是,pip3命令对我没有用.无论我尝试安装什么:

(bash)$pip3 install [new-lib] # pip 1.5.6

我得到:

Downloading/unpacking [new-lib]
    Cannot fetch index base URL https://pypi.python.org/simple/
    Could not find any downloads that satisfy the requirement [new-lib]
Cleaning up...
    No distributions at all found for [new-lib]
    Storing debug log for failure in ~/.pip/pip.log

尽管这不是(明确地)发生SSL错误,但似乎类似[5],成功的解决方法是在我的virtualenvs中使用easy_install安装较旧版本的pip.我指责这两个问题有关.

概括:

>寻找SSL证书失败错误的可能解决方案(在请求调用中不使用verify = False).
>尽管两种情况下使用的cert.pem完全相同,但我在python3.4中却收到了python2.7中的错误.
>尽管我可以使用openssl s_client -connect重新创建SSL错误,但可以通过为请求库使用的cert.pem指定-CAFile来避免此错误.
>我最好的猜测是,这是小牛队特有的问题,但我不知道如何进行.
>我希望找到一个解决方案,该解决方案还允许我按预期使用pip3安装python3.4软件包.

谢谢你的帮助!

[1]:我的机器上的python2.7是使用Enthought安装的.但是,安装系统版本的python2.7和请求库也可以.

[2]:有关使用python 2.7的类似问题,请参见openssl, python requests error: “certificate verify failed”

[3]:看来小牛在openssl中引入了更改? http://curl.haxx.se/mail/archive-2013-10/0036.html

[4]:从此处清除KeyChain.app:https://superuser.com/a/721629/261875

[5]:pip3的SSL错误:https://stackoverflow.com/a/22051466/2506078

解决方法:

从提供的其他信息来看,您似乎已经安装了32位的仅Python 3.4.1 from python.org版本.该版本主要用于OS X 10.5系统.因此,它与Apple随10.5提供的OpenSSL版本链接.您可以使用python.org中的64位/ 32位3.4.1安装程序来避免此问题;此版本建议用于OS X 10.6,并与Apple的更新版本的OpenSSL链接.否则,您可以使用curl或浏览器从PyPI手动下载发行版,并通过install pip从下载的文件中安装发行版.

标签:ssl,python-requests,osx-mavericks,python
来源: https://codeday.me/bug/20191121/2050466.html