如何获得Python请求以信任自签名SSL证书?


82
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

我知道我可以像这样传递Falseverify参数:

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

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


Answers:


60

尝试:

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

1
您可以同时执行并使用客户端证书吗?我对此有问题。
user1156544

9
请注意,您传递的.pem文件必须包含服务器的证书和所有中间证书。添加服务器的证书后,我花了几个小时试图弄清为什么它不起作用。
克里斯鲍勃(ChrisBob)

我添加了自签名的certificate.pem,它起作用了。
拉瑟尔

4
这种技术对我不起作用。我曾经ssl.get_server_certificate下载的证书(self-signed.badssl.com, 443),将该证书保存到cert.pem,然后运行requests.get('https://self-signed.badssl.com/', verify='cert.pem'),但仍然失败并出现SSL错误(该证书是自签名的)。
詹森·库姆斯

41

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

requests.get(url, verify=path_to_bundle_file)

文档

您可以verify使用受信任的CA证书将路径传递到CA_BUNDLE文件。也可以通过REQUESTS_CA_BUNDLE环境变量指定此受信任CA的列表。


2
为了使它很清晰,底部具有变异cert=(...)客户端SSL,又名相互TLS。尽管很有趣,但它要稀有得多,而且不是真正的问题所在。
尼克T

@ nick-t感谢您的评论。您是对的,我删除了答案的底部,以使其不再那么冗长。
Jan-Philip Gehrcke博士

22

最简单的方法是导出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库解决了我的问题。
伊尔金

6

解决了需要多个证书的情况,如下所示:将多个根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

那是我一天中的“ ahhh”时刻...非常感谢...有了这个提示,我得到了我自己签名的吉拉证书才能工作... ;-)我知道也许有很多网站和答案描述了这一点。 ,但我找到了您的,所以您因帮助我解决我的问题而获得荣誉... d
alexrjs

4

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


谢谢。对我有用(REQUESTS_CA_BUNDLE变量对我而言无效)。
Pascal H.

0

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

例如:

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

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.