如何让 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
【讨论】:
环境变量是我需要让 PyCharm 使用存储在 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 证书?的主要内容,如果未能解决你的问题,请参考以下文章
如何允许用户在 iOS 中使用 AFNetworking 信任和固定自签名 SSL 证书