Python 请求抛出 SSL 错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30830901/
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 09:02:46  来源:igfitidea点击:

Python requests throwing SSL errors

pythonmacossslpython-requests

提问by Gideon Av

This is a followup to SSLError using requests for python:

这是使用 python 请求对 SSLError的后续:

I have just installed requestson a Mac OSX 10.8.5. My first attempt at doing requests.getfailed on missing certificate:

我刚刚安装requests在 Mac OSX 10.8.5 上。我第一次尝试在requests.get缺少证书时失败:

SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

  • The thread above says to look for /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/re??quests/cacert.pembut actually I don't even have a .../site-packages/requestsdirectory. It's not clear to me if this should have been added by the installation (I used pip)

  • Further threads and the requestsdocs say to install certifi, so I did. But now I get a different error:

    python -c 'import requests; requests.get("https://api.github.com/events")'    /usr/lib/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
      InsecurePlatformWarning
    Traceback (most recent call last):
    ...
      File "/usr/lib/anaconda/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
        raise SSLError(e, request=request)
    requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
    
  • 上面的线程说要查找,/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/re??quests/cacert.pem但实际上我什至没有.../site-packages/requests目录。我不清楚这是否应该由安装添加(我使用过pip

  • 进一步的线程和requests文档说要安装certifi,所以我做到了。但现在我得到一个不同的错误:

    python -c 'import requests; requests.get("https://api.github.com/events")'    /usr/lib/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
      InsecurePlatformWarning
    Traceback (most recent call last):
    ...
      File "/usr/lib/anaconda/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
        raise SSLError(e, request=request)
    requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
    

Thanks!

谢谢!

回答by boaz_shuster

Notice that you're using HTTPS. As mentioned in the Requests manual

请注意,您正在使用HTTPS. 如请求手册中所述

To check a host's SSL certificate, you can use the verify argument [...] By default, verify is set to True

要检查主机的 SSL 证书,您可以使用 verify 参数 [...] 默认情况下,verify 设置为 True

Here are few ways to fix that:

这里有几种方法可以解决这个问题:

Update OpenSSL (probably will solve your problem)

更新 OpenSSL(可能会解决您的问题)

Taken from here:

取自这里

If you encounter one of the following errors:

error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm
The software you are using might be compiled with a version too old of OpenSSL that does not take certificates signed with sha256WithRSAEncryption into account.

It requires at least OpenSSL 0.9.8o for a total management of SHA256. OpenSSl 0.9.7m only assures a partial management, for server mode only.

如果您遇到以下错误之一:

error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm
The software you are using might be compiled with a version too old of OpenSSL that does not take certificates signed with sha256WithRSAEncryption into account.

它至少需要 OpenSSL 0.9.8o 才能对 SHA256 进行全面管理。OpenSSl 0.9.7m 仅保证部分管理,仅适用于服务器模式。

Check your opensslversion by

检查您的openssl版本

openssl version
OpenSSL 1.0.1k-fips 8 Jan 2015

If you have a smaller version than OpenSSL0.9.8o, you have to update its version (OS X):

如果您的版本小于OpenSSL0.9.8o,则必须更新其版本 (OS X):

brew update
brew install openssl
brew link --force openssl

If that doesn't work, try this way:

如果这不起作用,请尝试以下方法:

brew uninstall openssl
rm -rf /usr/local/openssl
brew install openssl
  • there's an issue with opensslinstalled before OS X 10.10.3and reinstalling it fixes it
  • these command lines will uninstall openssl, remove its folder from your hard-disk and install it again (the updated version)
  • openssl之前OS X 10.10.3安装有问题,重新安装即可解决
  • 这些命令行将卸载openssl,从硬盘中删除其文件夹并重新安装(更新版本)

Install certifi

安装 certifi

Taken from here

取自这里

By default Requests bundles a set of root CAs that it trusts, sourced from the Mozilla trust store. However, these are only updated once for each Requests version. This means that if you pin a Requests version your certificates can become extremely out of date.

From Requests version 2.4.0 onwards, Requests will attempt to use certificates from certifi if it is present on the system. This allows for users to update their trusted certificates without having to change the code that runs on their system.

For the sake of security we recommend upgrading certifi frequently!

默认情况下,Requests 捆绑了一组它信任的根 CA,这些根 CA 来自 Mozilla 信任存储。但是,对于每个请求版本,这些仅更新一次。这意味着如果您固定请求版本,您的证书可能会变得非常过时。

从 Requests 版本 2.4.0 开始,Requests 将尝试使用来自 certifi 的证书(如果它存在于系统上)。这允许用户更新他们的可信证书,而无需更改在其系统上运行的代码。

为了安全起见,我们建议经常升级证书!

In other word, try to install certifi, if you have Request 2.4.0or newer:

换句话说,certifi如果您有Request 2.4.0或更新,请尝试安装:

pip install certifi

Hopefully, this will fix the problem.

希望这能解决问题。

Use different version of OpenSSL and Requests

使用不同版本的 OpenSSL 和请求

Looking into it using Google, I have found that there is a problem with OpenSSL in Python 2:

使用谷歌查看它,我发现 Python 2 中的 OpenSSL 存在问题:

However, I am using Python 2.7.6, Requests 2.2.1and OpenSSL 1.0.1f 6 Jan 2014and everything runs correctly.

不过,我使用的Python 2.7.6Requests 2.2.1OpenSSL 1.0.1f 6 Jan 2014一切正常运行。

Pass the certificate

通过证书

In other cases, you may need to tell requests.getthe path to the certificate file, if the host's certificate was signed by you.

在其他情况下,requests.get如果主机的证书是由您签署的,您可能需要告诉证书文件的路径。

requests.get("https://api.github.com/events", verify=True, cert=['/path/to/my/ca.crt'])

Set the verify argument to False (NOT RECOMMENDED!)

将验证参数设置为 False(不推荐!)

In case you want to avoid the certificate verification, you have to pass verify=Falseto the request.getmethod.

如果您想避免证书验证,则必须传递verify=Falserequest.get方法。

python -c 'import requests; requests.get("https://api.github.com/events", verify=False)'

or from script.pyfile:

或来自script.py文件:

import requests
res = requests.get("https://api.github.com/events", verify=False)
print res

terminal:

终端:

$ python script.py
<Response [200]>

Important: Very bad idea; You can be MITMattacked, which is a critical security vulnerability.

重要提示:非常糟糕的主意;您可能会受到 MITM攻击,这是一个严重的安全漏洞。