Python 请求 - 如何使用系统 ca 证书(debian/ubuntu)?

新手上路,请多包涵

我已经在 debian 的 /usr/share/ca-certificates/local 中安装了一个自签名根 ca 证书,并使用 sudo dpkg-reconfigure ca-certificates 安装了它们。此时 true | gnutls-cli mysite.local 很高兴,并且 true | openssl s_client -connect mysite.local:443 很高兴,但是python2和python3请求模块坚持认为它对证书不满意。

蟒蛇2:

 Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 70, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 609, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 497, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)

蟒蛇3

 Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/bin/python3.5/site-packages/requests/api.py", line 70, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/bin/python3.5/site-packages/requests/api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/bin/python3.5/site-packages/requests/sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/bin/python3.5/site-packages/requests/sessions.py", line 609, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/bin/python3.5/site-packages/requests/adapters.py", line 497, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)

为什么 python 忽略系统 ca-certificates 包,我该如何集成它?

原文由 ThorSummoner 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

来自 https://stackoverflow.com/a/33717517/1695680

要使 python 请求使用系统 ca-certificates 包,需要告诉它在它自己的嵌入式包上使用它

export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt


Requests 在此处嵌入其捆绑包,以供参考:

 /usr/local/lib/python2.7/site-packages/requests/cacert.pem
/usr/lib/python3/dist-packages/requests/cacert.pem

或者在较新的版本中使用附加包从以下位置获取证书: https ://github.com/certifi/python-certifi

要验证从哪个文件加载证书,您可以尝试:

 Python 3.8.5 (default, Jul 28 2020, 12:59:40)
>>> import certifi
>>> certifi.where()
'/etc/ssl/certs/ca-certificates.crt'

原文由 ThorSummoner 发布,翻译遵循 CC BY-SA 4.0 许可协议

最近我为此苦苦挣扎了一个星期左右。我终于找到了在 Python 中验证自签名或私人签名证书的方法。您需要创建自己的证书捆绑文件。无需在每次更新库时更新晦涩的证书包,或向系统证书库添加任何内容。

首先运行您之前运行的 openssl 命令,但添加 -showcerts。 openssl s_client -connect mysite.local:443 -showcerts 这会给你一个长输出,在顶部你会看到整个证书链。通常,这意味着三个证书,依次为网站证书、中间证书和根证书。我们只需要将根证书和中间证书以相反的顺序放入下一个文件中。

将最后一个证书(根证书)复制到一个新的文本文件中。抓住之间的东西,包括:

 -----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

将中间证书(也称为中间证书)复制到根证书下的新文本文件。再次抓住 Begin 和 End Certificate 行以及两者之间的所有内容。

将此文本文件保存到 Python 脚本所在的目录。我的建议是调用它 CertBundle.pem 。 (如果你给它一个不同的名字,或者把它放在你的文件夹结构的其他地方,确保验证行反映了这一点。)更新你的脚本以引用新的证书包:

 response = requests.post("https://www.example.com/", headers=headerContents, json=bodyContents, verify="CertBundle.pem")

就是这样。如果您只有根证书或中间证书,则 Python 无法验证整个证书链。但是,如果您将这两个证书都包含在您创建的证书包中,则 Python 可以验证中间证书是否由根证书签名,然后当它访问该网站时,它可以验证该网站的证书是否由中间证书签名.

编辑:修复了证书包的文件扩展名。此外,还修复了一些语法错误。

原文由 fryad 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题