2015-05-22 89 views
29
import requests 
data = {'foo':'bar'} 
url = 'https://foo.com/bar' 
r = requests.post(url, data=data) 

如果URL中使用自签名的证书,这将失败,并如何让Python请求信任自签名的SSL证书?

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) 

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

+0

http://stackoverflow.com/questions/10667960/python-requests-throwing-up-sslerror?rq=1 – Ajay

回答

27

尝试:

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

随着verify参数,你可以提供一个自定义的证书颁发机构束(http://docs.python-requests.org/en/latest/user/advanced/):

requests.get(url, verify=path_to_bundle) 

您可以通过验证路径与颁发证书的CA_BUNDLE文件 可信CA。此信任的CA列表也可以通过 REQUESTS_CA_BUNDLE环境变量指定。

您还可以指定一个本地证书作为客户端证书使用, 为单个文件(包含私钥和证书)或 既是文件的路径的元组:

>>> requests.get('https://kennethreitz.com', cert=('/path/server.crt', '/path/key')) 
<Response [200]> 
7

最容易的是导出指向您的私人证书颁发机构或特定证书包的变量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 
2

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

柜面有人碰巧在这里降落(像我一样)希望增加一个CA(在我的情况查尔斯代理)对httplib2的,它看起来像你可以把它添加到cacerts.txt文件包含在Python包。

例如:

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

在其它解决方案中引用的环境变量似乎是具体的要求,并通过httplib2都在我的测试并没有回升。

0

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