使用Python ssl搭建TLS连接如何配置证书 解决未知CA报错
你遇到的报错是双向TLS认证场景下,对端证书的签发CA不在本地信任列表中导致的,以下是从零生成适配证书+调整代码的完整步骤:
一、前置准备
先创建证书存储目录,所有操作依赖openssl工具,一般Linux/macOS系统默认自带,Windows可直接安装openssl工具包:
mkdir -p certs && cd certs
二、生成根CA证书(信任锚)
根CA是所有证书的信任源头,服务端和客户端都需要信任这个根CA:
- 生成CA私钥:
openssl genrsa -out rootCA.key 2048 - 生成CA自签名证书(有效期设为10年,可自定义):
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt
执行时提示填写的信息中,Common Name 可随意填写比如Dev Root CA,其余字段可直接回车留空。
三、生成服务端证书
- 生成服务端私钥:
openssl genrsa -out dev_server.key 2048 - 生成服务端证书签名请求(CSR):
openssl req -new -key dev_server.key -out dev_server.csr
这里的Common Name必须填写服务端实际对外提供服务的IP或域名,本地测试用127.0.0.1就填127.0.0.1,其余字段可随意填写,不要和根CA的Common Name重复即可。 - 用根CA签发服务端证书:
openssl x509 -req -in dev_server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out dev_server.crt -days 365 -sha256
四、生成客户端证书
- 生成客户端私钥:
openssl genrsa -out dev_client.key 2048 - 生成客户端证书签名请求(CSR):
openssl req -new -key dev_client.key -out dev_client.csr
Common Name 可填写客户端标识比如Dev Client,其余字段可随意填写。 - 用根CA签发客户端证书:
openssl x509 -req -in dev_client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out dev_client.crt -days 365 -sha256
五、调整服务端代码
你原来的代码没有开启客户端证书校验,也没有加载信任CA列表,需要补充对应配置,调整后完整代码如下:
from socket import socket, AF_INET, SOCK_STREAM import ssl import os certs_path = "certs/" SERVER_CERT = os.path.join(certs_path, "dev_server.crt") SERVER_KEY = os.path.join(certs_path, "dev_server.key") # 信任的根CA证书路径 CA_ROOT = os.path.join(certs_path, "rootCA.crt") ip = '127.0.0.1' port = 8443 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) context.load_cert_chain(SERVER_CERT, SERVER_KEY) # 开启客户端证书强制校验 context.verify_mode = ssl.CERT_REQUIRED # 加载信任的根CA,load_verify_locations参数传入信任的CA证书文件即可,多个信任CA可拼接为同一个PEM文件传入 context.load_verify_locations(CA_ROOT) sock = socket(AF_INET, SOCK_STREAM) sock.bind(('', port)) sock.listen(5) print(f"Listening for TCP connections on port: {port}") while True: connection, sender = sock.accept() sec_sock = context.wrap_socket(connection, server_side=True) request = sec_sock.read() decoded = request.decode("utf-8") print(f"Received {decoded} from {sender[0]}:{sender[1]}")
六、C语言客户端配置要求
客户端侧需要做两个配置:
- 加载根CA证书
rootCA.crt作为信任锚,校验服务端证书合法性 - 加载客户端自身的证书
dev_client.crt和私钥dev_client.key,用于服务端对客户端的身份校验
如果你不需要双向认证,只是需要客户端校验服务端证书,那不需要开启服务端的verify_mode和load_verify_locations配置,仅在客户端加载rootCA.crt作为信任锚即可解决报错。
内容的提问来源于stack exchange,提问作者Eoin McMahon
相关产品推荐
相关产品推荐

