客户端证书在curl中可以工作,但在Python中无法使用

3

使用 curl 命令可以连接到需要特定证书的服务器。

curl -E ./file.crt.pem --key ./file.key.pem -k https://server.url

curl版本: 7.29.0

但是当使用Python的requests库时,我遇到了一个错误:

import requests
cert_file_path = "file.crt.pem"
key_file_path = "file.key.pem"
cert = (cert_file_path, key_file_path)
url = 'https://server.url'
r = requests.post(url, cert=cert, verify=False)

错误:

SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_read_bytes', 'tlsv1 alert unknown ca')])"))

Python版本:v3.7

我错过了什么?


很可能是因为Python没有使用系统的受信任证书存储。请尝试这个问题:https://dev59.com/L1gQ5IYBdhLWcg3wSyIO - Robert Kearns
@RobertKearns 我尝试了那里的解决方案,但都没有起作用。我也在golang中尝试了,但它会出现握手失败的情况。最终我编写了一个curl绑定库... - Ali Padida
2个回答

2

这篇答案的评论帮助我理解了这个问题。

请按如下方式更新您的代码:

import requests
cert_file_path = "file.crt.pem"
key_file_path = "file.key.pem"
cert = (cert_file_path, key_file_path)
url = 'https://server.url'
r = requests.post(url, cert=cert, verify="path/to/ca_public_keys.pem") # replace with your file

我假设您正在使用自签名证书,因此您需要指定包含颁发您自签名证书的CA的公共证书的.pem文件。 请确保包括中间证书,否则请求库将抛出tlsv1 alert unknown ca错误。

您可以通过在终端中键入openssl x509 -noout -in file.crt.pem -issuer来检查客户端证书的颁发者。


2

请求模块检查环境变量 REQUESTS_CA_BUNDLE 是否存在证书文件。因此,只需执行以下操作:

export REQUESTS_CA_BUNDLE=/absolute/path/to/your/file.crt.pem

您的 Python 代码将会简单如下所示:
import requests

url = 'https://server.url'
r = requests.post(url)
print(r.text)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接