小牛的python中的SSL证书验证失败 [英] SSL certificate verification failure in python on Mavericks

查看:96
本文介绍了小牛的python中的SSL证书验证失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了持久性 SSL 验证问题.

I'm stuck on a persistent SSL verification issue.

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

I discovered the error while building a Django app that had users authenticate using Mozilla Persona.

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

我得到一个 SSL: CERTIFICATE_VERIFY_FAILEDrequests 回溯到 urllib3ssl:

I get a SSL: CERTIFICATE_VERIFY_FAILED tracing back from requests to urllib3 to 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 时我没有遇到同样的问题:

Difference between python3 and python2

Here's where it starts to get interesting: I don't get the same issue when using python2.7:

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

我的第一个想法是 requests 的两个版本可能使用了不同的证书[1],所以我很惊讶地发现这两个文件完全相同:

My first thought was that the two versions of requests might be using different certs[1], so I was pretty surprised to find the two files were exactly the same:

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

Error recreated in openssl and solved using -CAFile

Interestingly, the issue is not limited to 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 以进行验证.但是,我可以指定 requests 包正在使用的相同证书并且我没有收到相同的错误这一事实仍然很有趣:

Edit A comment from Steffen informed me that this "debugging" method isn't actually informative, as s_client expects a -CApath in order to verify. However, the fact that I can specify the same certificate that the requests package is using and I don't get the same error is still interesting:

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

在这一点上,我完全脱离了我的元素.我不知道这是否真的是 openssl 问题,还是关于 OSX Mavericks[3] 的问题.这是我正在使用的 openssl 版本:

At this point, I'm completely out of my element. I don't know is if this is really an openssl issue, or something about OSX Mavericks[3]. Here's the version of openssl I'm using:

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

小牛队 KeyChain.app

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

Mavericks KeyChain.app

For OS-specific solutions, I've tried clearing my login KeyChain[4], to no avail.

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

There's one last bit of evidence that may or may not be relevant. python3.4 ships with pip intact. However, the pip3 command is useless to me. No matter what I try to install:

(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],一个成功的解决方法是在我的 virtualenv<中使用 easy_install 安装旧版本的/code>s[5].我交叉手指说这两个问题是相关的.

Although this isn't (explicitly) an SSL error, it seems similar[5] and a successful workaround has been to install an older version of pip using easy_install in my virtualenvs[5]. I'm crossing my fingers that the two issues are related.

回顾:

  • 寻求 SSL 证书失败错误的可能解决方案(在 requests 调用中不使用 verify = False).
  • 我在 python3.4 中得到错误,但在 python2.7 中没有得到错误,即使在这两种情况下使用的 cert.pem 完全相同.
  • 虽然我可以使用 openssl s_client -connect 重新创建 SSL 错误,但我可以通过将 -CAFile 指定给请求库使用的 cert.pem 来避免它.
  • 我最好的猜测是这是小牛队特有的问题,但我不知道如何继续.
  • 我希望找到一种解决方案,该解决方案还允许我按预期使用 pip3 安装 python3.4 软件包.
  • Seeking possible solutions for SSL certificate failure error (without using verify = False in the requests calls).
  • I get the error in python3.4 but not python2.7 even though the cert.pem used in both cases is exactly the same.
  • Though I can recreate an SSL error using openssl s_client -connect I can avoid it by specifying -CAFile to the cert.pem used by the requests library.
  • My best guess is that this is an issue particular to Mavericks, but I have no idea how to proceed.
  • I'm hoping to find a solution that also allows me to use pip3 to install python3.4 packages as expected.

感谢您的帮助!

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

[1]: python2.7 on my machine was installed using Enthought. But installing a system version of python2.7 and the requests library works too.

[2]:见openssl,python请求错误:"certificate verify使用 python 2.7 的类似问题失败

[3]:好像小牛队在openssl中引入了变化?http://curl.haxx.se/mail/archive-2013-10/0036.html

[3]: It seems Mavericks introduced a change in openssl? http://curl.haxx.se/mail/archive-2013-10/0036.html

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

[4]: Clearning KeyChain.app from here: https://superuser.com/a/721629/261875

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

[5]: SSL error with pip3: https://stackoverflow.com/a/22051466/2506078

推荐答案

从您提供的附加信息来看,您似乎已经安装了 32 位版本的 python.org 的 Python 3.4.1.此版本主要用于 OS X 10.5 系统;因此,它与 Apple 提供的 OpenSSL 版本 10.5 相关联.您可以通过使用来自 python.org 的 64 位/32 位 3.4.1 安装程序来避免此问题;此版本推荐用于 OS X 10.6+,并与 Apple 的 OpenSSL 的较新版本相关联.否则,您可以使用 curl 或浏览器从 PyPI 手动下载发行版,然后安装 pip 从下载的文件中安装它们.

From the additional information that you have supplied, it appears you have installed the 32-bit-only version of Python 3.4.1 from python.org. This version is intended primarily for use on OS X 10.5 systems; as such, it is linked with the version of OpenSSL supplied by Apple with 10.5. You can avoid this problem by using the 64-bit/32-bit 3.4.1 installer from python.org; this version is recommended for OS X 10.6+ and is linked with the newer version of Apple's OpenSSL. Otherwise, you could manually download distributions from PyPI using curl or a browser and have install pip install them from the downloaded file(s).

这篇关于小牛的python中的SSL证书验证失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆