Python客户端如何使用无密钥PEM证书完成HTTPS服务器认证?
问题:无密钥PEM证书在Python requests中使用的SSL错误与401问题
服务器提供商提供了一份无密钥的PEM格式证书,用于Python客户端与服务器通信,证书内容如下:
-----BEGIN CERTIFICATE----- MIIFSDCCBDCg........................................ -----END CERTIFICATE-----
尝试以下代码时出现SSL错误:
r = requests.post(url, data=payload, headers=headers, cert=('cert.pem'))
报错信息:
requests.exceptions.SSLError: HTTPSConnectionPool(host='sauth-external.apple.com', port=443): Max retries exceeded with url: /api/v1.0/external/authEntityRequests (Caused by SSLError(SSLError(9, '[SSL] PEM lib (_ssl.c:4029)')))
改用verify参数后返回401错误:
r = requests.post(url, data=payload, headers=headers, verify='cert.pem')
请问遗漏了什么?如何实现连接并完成认证?
解答
先明确两个参数的核心区别
cert参数用于客户端证书认证:要求你同时提供客户端证书和对应的私钥文件(可以是分开的.pem+.key,也可以是合并在同一个文件里的证书+私钥)。你只有无密钥的证书,SSL库找不到私钥完成客户端身份校验,这就是触发PEM lib错误的原因。verify参数用于验证服务器SSL证书:告诉requests用你提供的证书校验服务器返回的证书是否可信。返回401说明SSL连接已经建立,但服务器要求你完成客户端认证,而你没提供对应的客户端身份凭证,因此被服务器拒绝。
正确的解决步骤
确认服务器认证要求:
- 如果服务器需要双向SSL认证,你必须联系提供商获取这份证书对应的私钥文件,没有私钥无法完成客户端身份验证。
- 如果服务器仅要求单向SSL(客户端信任服务器)但需要其他身份认证(比如API密钥、OAuth令牌),401错误就是因为你没补充这些必要的认证信息。
对应场景的代码写法:
- 仅验证服务器证书:确保
cert.pem是服务器的根证书/中间证书,保留verify='cert.pem',同时在headers中添加服务器要求的认证字段(比如Authorization: Bearer {token}或自定义密钥头)。 - 客户端证书认证:拿到私钥后,将证书和私钥传给
cert参数:# 证书和私钥分开的情况 r = requests.post(url, data=payload, headers=headers, cert=('client_cert.pem', 'client_key.pem')) # 证书和私钥合并在一个文件的情况 r = requests.post(url, data=payload, headers=headers, cert='combined_cert_key.pem')
- 仅验证服务器证书:确保
内容的提问来源于stack exchange,提问作者MOHAMED
相关产品推荐
相关产品推荐

