Python SSL连接报错ssl.SSLError: [SSL] PEM lib (_ssl.c:4044)求助
SSL连接报错ssl.SSLError: [SSL] PEM lib (_ssl.c:4044) 解决方法
报错信息
ssl.SSLError: [SSL] PEM lib (_ssl.c:4044)
环境信息
- Python版本:3.9.13
- OpenSSL版本:1.1
证书文件内容
-----BEGIN ENCRYPTED PRIVATE KEY----- <...............\> -----END ENCRYPTED PRIVATE KEY----- -----BEGIN CERTIFICATE----- <..........\> -----END CERTIFICATE-----
出错代码片段(错误触发于context.load_cert_chain行)
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile=certificate_path) # Make a GET request to the API headers = { 'User-ID': user_id, 'API-Key': api_key, 'Content-Type': 'application/json', } response = requests.get(api_url, headers=headers, verify=certificate_path)
已做排查
- 核实Python/OpenSSL版本兼容性
- 确认密钥与证书匹配
- 检查证书文件路径和权限无误
- 查阅
_ssl.c源码未定位根源 - 搜索同类问题未找到有效方案
问题根源与解决方案
核心原因
你的私钥是加密状态(标识为-----BEGIN ENCRYPTED PRIVATE KEY-----),而ssl.SSLContext.load_cert_chain方法默认无法读取加密私钥,必须显式提供解密密码,或使用解密后的私钥文件。
解决方法
方法1:直接传入私钥解密密码
修改load_cert_chain调用,添加password参数(注意密码需转为字节类型):
# 替换为你的私钥密码 context.load_cert_chain(certfile=certificate_path, password=b"your_private_key_password")
方法2:解密私钥后重新生成文件
用OpenSSL命令行解密私钥:
openssl pkcs8 -in certificate.pem -out decrypted_key.pem
执行后输入私钥密码完成解密,之后可将解密后的私钥与证书合并,或分开传入参数:
context.load_cert_chain(certfile="certificate.pem", keyfile="decrypted_key.pem")
额外修正:requests参数误用
代码中requests.get的verify参数是用来验证服务器证书的CA文件,若要使用客户端证书,应改用cert参数:
# 证书与私钥在同一文件时 response = requests.get(api_url, headers=headers, cert=certificate_path) # 证书与私钥分开存储时 response = requests.get(api_url, headers=headers, cert=("cert.pem", "decrypted_key.pem"))
内容的提问来源于stack exchange,提问作者Perl_Devloper
相关产品推荐
相关产品推荐

