Python 请求使用证书值而不是路径

Ufd*_*der 2 certificate python-3.x python-requests

我正在使用 python 请求模块进行 POST 调用:

import requests
response = requests.post( foo_url, 
                          json={"foo":"bar"}, 
                          headers=foo_headers,
                          verify='/path/to/cert' )
Run Code Online (Sandbox Code Playgroud)

这很好用。虽然可以直接使用证书的值而不是包含证书的文件的路径吗?

Quu*_*one 7

TLDR:答案肯定是“不,证书必须位于磁盘上的文件中”。原因是 OpenSSL 太糟糕了。

requests是基于urllib3,这是基于sslrequests获取顶级cert参数并将其分成名为cert_file和 的参数key_file,这些参数被传递给urllib3urllib3将它们原封不动地传递给ssl。并ssl期望它们是文件名。

Python 堆栈底部的具体罪魁祸首SSLContext.load_cert_chain来自ssl模块。这取决于_SSLContext,它是用 C 编写的。 C 代码_SSLContext.load_cert_chain这里。您可以看到,它确实 100% 需要文件系统路径!啊!

C 堆栈底部的罪魁祸首是 OpenSSL SSL_CTX_use_certificate_chain_file,它具有以下签名:

int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
Run Code Online (Sandbox Code Playgroud)

在 OpenSSL 中构建证书链的方法有很多,不涉及“仅打开文件并读入”,但它们要复杂得多,我想这就是为什么 Python 不ssl使用它们的原因......解释了为什么urllib3不使用它们,这也解释了为什么requests不使用它们。