简体   繁体   English

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

[英]How to get Python requests to trust a self signed SSL certificate?

import requests
data = {'foo':'bar'}
url = 'https://foo.com/bar'
r = requests.post(url, data=data)

If the URL uses a self signed certificate, this fails with如果 URL 使用自签名证书,则失败并显示

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

I know that I can pass False to the verify parameter, like this:我知道我可以将False传递给verify参数,如下所示:

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

However, what I would like to do is point requests to a copy of the public key on disk and tell it to trust that certificate.但是,我想做的是将请求指向磁盘上公钥的副本,并告诉它信任该证书。

尝试:

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

With the verify parameter you can provide a custom certificate authority bundle使用verify参数,您可以提供自定义证书颁发机构包

requests.get(url, verify=path_to_bundle_file)

From the docs :文档

You can pass verify the path to a CA_BUNDLE file with certificates of trusted CAs.您可以使用受信任的 CA 证书传递verify CA_BUNDLE 文件的路径。 This list of trusted CAs can also be specified through the REQUESTS_CA_BUNDLE environment variable.这个受信任的 CA 列表也可以通过 REQUESTS_CA_BUNDLE 环境变量指定。

The easiest is to export the variable REQUESTS_CA_BUNDLE that points to your private certificate authority, or a specific certificate bundle.最简单的方法是导出指向您的私有证书颁发机构或特定证书包的变量REQUESTS_CA_BUNDLE On the command line you can do that as follows:在命令行上,您可以按如下方式执行此操作:

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

If you have your certificate authority and you don't want to type the export each time you can add the REQUESTS_CA_BUNDLE to your ~/.bash_profile as follows:如果您拥有证书颁发机构并且不想每次都键入export ,则可以将REQUESTS_CA_BUNDLE添加到您的~/.bash_profile ,如下所示:

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

Case where multiple certificates are needed was solved as follows: Concatenate the multiple root pem files, myCert-A-Root.pem and myCert-B-Root.pem, to a file.需要多个证书的情况如下解决:将多个根 pem 文件 myCert-A-Root.pem 和 myCert-B-Root.pem 连接到一个文件中。 Then set the requests REQUESTS_CA_BUNDLE var to that file in my ./.bash_profile.然后将请求 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

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

If you're behind a corporate network firewall like I was, ask your network admin where your corporate certificates are, then:如果您像我一样在公司网络防火墙后面,请询问您的网络管理员您的公司证书在哪里,然后:

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

This fixed issues I had with requests and openssl.这解决了我在 requests 和 openssl 中遇到的问题。

All of the answers to this question point to the same path: get the PEM file, but they don't tell you how to get it from the website itself.这个问题的所有答案都指向相同的路径:获取 PEM 文件,但他们没有告诉您如何从网站本身获取它。

Getting the PEM file from the website itself is a valid option if you trust the site, such as on an internal corporate server.如果您信任该网站(例如在内部公司服务器上),则从网站本身获取 PEM 文件是一个有效的选择。 If you trust the site, why should you do this?如果您信任该网站,为什么要这样做? You should do this because it helps protect yourself and others from inadvertently re-using your code on a site that isn't safe.您应该这样做,因为它有助于保护您自己和他人免于在不安全的站点上无意中重复使用您的代码。

Here is how you can get the PEM file.以下是获取 PEM 文件的方法。

  1. Click on the lock next to the url.点击网址旁边的锁。 点击锁<\/a>

    <\/li>

  2. Navigate to where you can see the certificates and open the certificates.导航到可以查看证书的位置并打开证书。 导航查看证书<\/a>

    <\/li>

  3. Download the PEM CERT chain.下载 PEM CERT 链。 下载 PEM 链<\/a>

    <\/li>

  4. Put the .PEM file somewhere you script can access it and try verify=r"path\\to\\pem_chain.pem"<\/code> within your requests<\/code> call.将 .PEM 文件放在您的脚本可以访问的地方,并在您的requests<\/code>调用中尝试verify=r"path\\to\\pem_chain.pem"<\/code> 。

    <\/li><\/ol>

    r = requests.get(url, verify='\\path\\to\\public_key.pem')<\/code>

    "

Incase anyone happens to land here (like I did) looking to add a CA (in my case Charles Proxy) for httplib2, it looks like you can append it to the cacerts.txt file included with the python package.如果有人碰巧来到这里(就像我一样)希望为 httplib2 添加 CA(在我的例子中是 Charles Proxy),看起来您可以将它附加到 python 包中包含的cacerts.txt文件中。

For example:例如:

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

The environment variables referenced in other solutions appear to be requests-specific and were not picked up by httplib2 in my testing.其他解决方案中引用的环境变量似乎是特定于请求的,并且在我的测试中没有被 httplib2 选取。

You may try:你可以试试:

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

You can read more here: http://docs.python-requests.org/en/master/user/advanced/您可以在此处阅读更多信息: http : //docs.python-requests.org/en/master/user/advanced/

In a dev environment, using Poetry as virtual env provider on a Mac with Python 3.8 I used this answer https://stackoverflow.com/a/42982144/15484549 as base and appended the content of my self-signed root certificate to the certifi cacert.pem file.在开发环境中,在带有 Python 3.8 的 Mac 上使用 Poetry 作为虚拟环境提供程序我使用这个答案https://stackoverflow.com/a/42982144/15484549作为基础,并将我的自签名根证书的内容附加到证书cacert.pem 文件。

The steps in detail:详细步骤:

cd project_folder
poetry add requests
# or if you use something else, make sure certifi is among the dependencies
poetry shell
python
>>> import certifi
>>> certifi.where()
/path/to/the/certifi/cacert.pem
>>> exit()
cat /path/to/self-signed-root-cert.pem >> /path/to/the/certifi/cacert.pem
python the_script_you_want_to_run.py

I know it is an old thread.我知道这是一个旧线程。 However, I run into this issue recently.但是,我最近遇到了这个问题。 My python requests code does not accept the self-signed certificate but curl does.我的 python 请求代码不接受自签名证书,但 curl 接受。 It turns out python requests are very strict on the self-signed certificate.原来 python 请求对自签名证书非常严格。 It needs to be a root CA certificate.它需要是根 CA 证书。 In other words,换句话说,

Basic Constraints: CA:TRUE基本约束:CA:TRUE

Key Usage: Digital Signature, Non Repudiation, Key Encipherment, Certificate Sign密钥用途:数字签名、不可否认性、密钥加密、证书签名

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Python3 请求信任 badssl.com 的自签名证书 - How to trust self signed certificate of badssl.com with Python3 requests 如何允许 python 信任我服务器的 TLS 自签名证书:ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败 - How to allow python to trust my server's TLS self-signed certificate: ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed Python 请求:[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:自签名证书 - Python requests: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate 如何使用Python请求使用密码对自签名证书进行身份验证 - How to authenticate self signed certificate with password using Python requests 使用python自签名证书的ssl - ssl with self signed certificate using python 确定SSL证书是否使用Python自签名 - Determine if SSL certificate is self signed using Python 带有 Python SSL 插座的自签名证书 - Self signed Certificate with Python SSL socket 使用Python请求信任自签名证书 - Trusting self signed certificate with Python requests 在 Python 中使用带有自签名证书的请求时,证书验证失败 - Certificate Verify Failed when using Requests in Python with a self signed certificate 使用自签名证书将Metro应用连接到Python SSL服务器 - Connect a Metro app to a Python SSL server with a self-signed certificate
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM