如何修复Python SSL服务器中的ssl.SSLError: [SSL] PEM lib (_ssl.c:3921)错误?
解决 ssl.SSLError: [SSL] PEM lib 错误的方案
1. 修正证书文件路径
代码中使用的相对路径 SSH Chat/certificate.pem 是基于脚本运行的当前工作目录查找文件,而非脚本所在目录。优先使用绝对路径避免路径歧义:
# 替换为你的证书实际绝对路径 certfile='C:/Users/[USER]/Documents/Programming/Python/SSH Chat/certificate.pem'
或者通过脚本路径动态拼接,适配不同运行场景:
import os script_dir = os.path.dirname(os.path.abspath(__file__)) certfile = os.path.join(script_dir, 'certificate.pem')
2. 确认证书格式与完整性
PEM格式的证书必须包含标准头部和尾部:
- 证书部分:
-----BEGIN CERTIFICATE-----开头,-----END CERTIFICATE-----结尾 - 私钥部分:若证书文件未包含私钥,需单独指定
keyfile参数,私钥头部为-----BEGIN PRIVATE KEY-----或-----BEGIN RSA PRIVATE KEY-----
如果证书是DER等非PEM格式,用OpenSSL转换:
openssl x509 -inform der -in certificate.cer -out certificate.pem
拆分证书与私钥时,修改代码如下:
httpd.socket = ssl.wrap_socket( httpd.socket, certfile='path/to/certificate.pem', keyfile='path/to/private_key.pem', server_side=True, ssl_version=ssl.PROTOCOL_TLS )
3. 检查文件读取权限
Windows下右键证书文件→属性→安全,确认当前用户拥有读取权限;Linux/macOS执行以下命令设置权限:
chmod 644 certificate.pem private_key.pem
4. 使用推荐的SSLContext API(替代弃用的wrap_socket)
Python 3.2+ 官方推荐使用 SSLContext 替代老旧的 wrap_socket,写法更安全清晰:
import ssl import http.server import os script_dir = os.path.dirname(os.path.abspath(__file__)) certfile = os.path.join(script_dir, 'certificate.pem') keyfile = os.path.join(script_dir, 'private_key.pem') context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain(certfile=certfile, keyfile=keyfile) httpd = http.server.HTTPServer(('localhost', 443), http.server.SimpleHTTPRequestHandler) httpd.socket = context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever()
内容的提问来源于stack exchange,提问作者ProbablyIdiot
相关产品推荐
相关产品推荐

