如何让 Python 请求信任自签名 SSL 证书?

Posted

技术标签:

【中文标题】如何让 Python 请求信任自签名 SSL 证书?【英文标题】:How to get Python requests to trust a self signed SSL certificate? 【发布时间】:2015-08-05 00:25:30 【问题描述】:
import requests
data = 'foo':'bar'
url = 'https://foo.com/bar'
r = requests.post(url, data=data)

如果 URL 使用自签名证书,则会失败并显示

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

我知道我可以将False 传递给verify 参数,如下所示:

r = requests.post(url, data=data, verify=False)

但是,我想做的是将请求指向磁盘上的公钥副本,并告诉它信任该证书。

【问题讨论】:

***.com/questions/10667960/… 【参考方案1】:

尝试:

r = requests.post(url, data=data, verify='/path/to/public_key.pem')

【讨论】:

你能做同样的事情并同时使用客户端证书吗?我遇到了这个问题。 请注意,您传递的 .pem 文件必须包含服务器的证书和任何中间证书。我花了几个小时试图弄清楚为什么在添加服务器证书后它不起作用。 这项技术对我不起作用。我使用ssl.get_server_certificate 下载了(self-signed.badssl.com, 443) 的证书,将该证书保存到cert.pem,然后运行requests.get('https://self-signed.badssl.com/', verify='cert.pem'),它仍然失败并出现SSL 错误(该证书是自签名的)。 @ChrisBob 我感激不尽。您的评论比对此许多问题的公认答案更有价值(仅重复请求文档中的内容)。在拉了我几个小时的头发后,你的评论让我朝着正确的方向前进...... 作为参考(可能是我未来的自己),我必须通过单击 Firefox 中的锁定图标 > 显示连接详细信息 > 更多信息 > 查看证书 > 下载将证书下载为 .pem 文件b>“PEM(链)”。 (链)是我缺少的重要部分,因为替代“PEM(证书)”将处理请求。【参考方案2】:

使用verify 参数,您可以提供自定义证书颁发机构包

requests.get(url, verify=path_to_bundle_file)

来自the docs:

您可以将verify 的路径传递给带有证书的 CA_BUNDLE 文件 受信任的 CA。这个受信任的 CA 列表也可以通过 REQUESTS_CA_BUNDLE 环境变量。

【讨论】:

【参考方案3】:

最简单的方法是导出变量REQUESTS_CA_BUNDLE,它指向您的私有证书颁发机构或特定的证书包。在命令行上,你可以这样做:

export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem
python script.py

如果您有证书颁发机构并且不想每次都输入export,您可以将REQUESTS_CA_BUNDLE 添加到您的~/.bash_profile,如下所示:

echo "export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem" >> ~/.bash_profile ; source ~/.bash_profile

【讨论】:

环境变量是我需要让 PyC​​harm 使用存储在 OpenSSL 证书文件中的证书。 我在链中有一个自签名证书。这个解决方案解决了我的 boto3 库问题。【参考方案4】:

需要多个证书的情况解决如下: 将多个根 pem 文件 myCert-A-Root.pem 和 myCert-B-Root.pem 连接到一个文件。然后将请求 REQUESTS_CA_BUNDLE var 设置为我的 ./.bash_profile 中的那个文件。

$ cp myCert-A-Root.pem ca_roots.pem
$ cat myCert-B-Root.pem >> ca_roots.pem
$ echo "export REQUESTS_CA_BUNDLE=~/PATH_TO/CA_CHAIN/ca_roots.pem" >> ~/.bash_profile ; source ~/.bash_profile

【讨论】:

那是我一天中的“啊哈”时刻......非常感谢......有了这个提示,我得到了我的自签名 jira 证书...... ;-) 我知道可能有数以百计的网站和答案都描述了这一点,但我找到了你的,所以你得到了我的信任,帮助我解决了我的问题...... d【参考方案5】:

设置 export SSL_CERT_FILE=/path/file.crt 应该可以完成这项工作。

【讨论】:

谢谢。对我有用(而 REQUESTS_CA_BUNDLE 变量在我的情况下无效)。 在您的终端中【参考方案6】:

如果您像我一样位于公司网络防火墙后面,请询问您的网络管理员您的公司证书在哪里,然后:

import os
os.environ["REQUESTS_CA_BUNDLE"] = 'path/to/corporate/cert.pem'
os.environ["SSL_CERT_FILE"] = 'path/to/corporate/cert.pem'

这解决了我在 requests 和 openssl 中遇到的问题。

【讨论】:

【参考方案7】:

如果有人碰巧来到这里(就像我一样)希望为 httplib2 添加 CA(在我的情况下为 Charles Proxy),看起来您可以将其附加到 python 包中包含的 cacerts.txt 文件中。

例如:

cat ~/Desktop/charles-ssl-proxying-certificate.pem >> /usr/local/google-cloud-sdk/lib/third_party/httplib2/cacerts.txt

其他解决方案中引用的环境变量似乎是特定于请求的,在我的测试中没有被 httplib2 拾取。

【讨论】:

【参考方案8】:

你可以试试:

settings = s.merge_environment_settings(prepped.url, None, None, None, None)

您可以在这里阅读更多内容:http://docs.python-requests.org/en/master/user/advanced/

【讨论】:

哦,是的,那个旧的 readthedocs 迷宫? 链接截至今天:requests.readthedocs.io/en/latest/user/advanced

以上是关于如何让 Python 请求信任自签名 SSL 证书?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个自签名的SSL证书

使用 HttpClient 信任自签名证书

如何允许用户在 iOS 中使用 AFNetworking 信任和固定自签名 SSL 证书

如何添加自签名SSL证书 自签名SSL证书存风险

如何在 Chrome 信任的本地 Windows 虚拟主机开发机器上创建/安装自签名 SSL 证书? [复制]

MAC申请自签名的ssl证书