【问题标题】:How to get Python requests to trust a self signed SSL certificate?如何让 Python 请求信任自签名 SSL 证书?
【发布时间】: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)

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

【问题讨论】:

标签: python ssl python-requests


【解决方案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/

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-10
        • 2019-09-03
        • 1970-01-01
        • 2018-10-08
        • 2023-03-11
        • 2011-09-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多