Python使用系统SSL证书?

jam*_*oks 6 python ssl curl authorize.net

我跑进最近Authorize.net SSL证书失效崩溃的最后一周。

我终于能够让 curl 接受他们的证书:

$ curl -Iv https://secure.authorize.net
...
*  SSL certificate verify ok.
...
Run Code Online (Sandbox Code Playgroud)

但是python仍然通过请求拒绝它:

>>> requests.get('https://secure.authorize.net', verify=True)
...
  InsecurePlatformWarning
Run Code Online (Sandbox Code Playgroud)

在我的代码中:

File "/usr/lib/python2.7/ssl.py", line 405, in do_handshake
    self._sslobj.do_handshake()
SSLError: [Errno 1] _ssl.c:510: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Run Code Online (Sandbox Code Playgroud)

谁能告诉我为什么 python 似乎没有使用系统证书进行验证?关于修复的任何想法?

编辑

我正在使用 Ubuntu 并以这种方式安装证书:

sudo curl -o /usr/local/share/ca-certificates/entrust_ssl_ca.crt https://www.entrust.net/downloads/binary/entrust_ssl_ca.cer
sudo update-ca-certificates
Run Code Online (Sandbox Code Playgroud)

运行后,curl 正常工作,但 python 仍然无法识别证书。

lar*_*sks 4

您没有提及您正在使用的操作系统或安装证书的位置以使它们可供 Curl 使用。

我在我的系统上使用strace它来查看Python在哪里寻找证书。在我的 Fedora 系统上,Python 使用的是/etc/pki/tls/certs/ca-bundle.crt,这是 Fedora、Red Hat 和类似系统上的标准位置。

在 Ubuntu 上,Python 正在寻找/etc/ssl/certs/ca-certificates.crt.

根据文档

您可以使用可信 CA 的证书来验证 CA_BUNDLE 文件的路径。还可以通过 REQUESTS_CA_BUNDLE 环境变量指定此受信任 CA 列表。

...因此您可以为您的应用程序提供独立于系统上安装的 CA 证书的列表。

更新

运行openssl s_client -showcerts -connect secure.authorize.net:443显示该*.authorize.net证书由“Entrust Certification Authority - L1K”证书签名,该证书由“Entrust Root Certification Authority - G2”证书签名,该证书由“Entrust Root Certification Authority”证书签名。您安装的证书entrust_ssl_ca.crt是“Entrust.net Secure Server Certification Authority”,它是“以上都不是”。

我只需访问http://www.entrust.com/get-support/ssl-certificate-support/root-certificate-downloads/并下载所有内容,但上述链中的顶级证书就是这个。这是下载页面上列出的第二个证书。