4. 混合密钥交换在TLS链路中的部署验证
测试环境与部署对象
本节在隔离测试环境中完成一次可复现的混合密钥交换部署验证。测试对象为一台运行 Nginx 1.27 的 Web 服务端与一台使用 OpenSSL 3.5 客户端的测试机,二者通过本地回环或测试网段通信,不涉及生产流量。验证的核心是:在 TLS 1.3 握手中同时启用 X25519MLKEM768(X25519 与 ML-KEM-768 的混合组)与传统 X25519,确认协商结果、抓包可见性以及握手延迟与兼容性表现。
需要先明确两个前提。第一,混合密钥交换只影响 TLS 1.3 的 key_share 与密钥派生,不改变证书签名算法,因此本节不涉及证书链改造。第二,X25519MLKEM768 在 OpenSSL 3.5 中作为命名组存在,服务端与客户端必须同时支持该组才可能协商成功;任一端不支持时会回退到双方共同支持的经典组,这正是兼容性观察的重点。
服务端与客户端配置
服务端在 Nginx 的 server 块中通过 ssl_conf_command 指定组顺序,把混合组放在首位,保留 X25519 作为回退:
server {
listen 8443 ssl;
server_name pq-test.local;
ssl_certificate /etc/nginx/certs/test.crt;
ssl_certificate_key /etc/nginx/certs/test.key;
ssl_protocols TLSv1.3;
# 混合组优先,X25519 作为回退组
ssl_conf_command Groups X25519MLKEM768:X25519;
location / {
return 200 "pq-kex-ok\n";
}
}
客户端使用 OpenSSL 命令行发起握手并显式指定组,便于对照实验:
# 混合组优先
openssl s_client -connect 127.0.0.1:8443 -tls1_3 \
-groups X25519MLKEM768:X25519 -brief
# 仅经典组,用于兼容性对照
openssl s_client -connect 127.0.0.1:8443 -tls1_3 \
-groups X25519 -brief
配置完成后先做语法检查再重载,避免因组名拼写错误导致服务启动失败:
nginx -t && nginx -s reload
握手协商与抓包确认
用 -brief 模式观察协商结果,输出中会出现协商到的组名。混合组成功时可见 Negotiated TLS1.3 group: X25519MLKEM768;若客户端只提供 X25519,则显示 X25519。这一步是判断“是否真的用上了混合密钥交换”的第一手依据。
抓包确认使用 tcpdump 保存握手报文,再用 Wireshark 或 tshark 查看 ClientHello 的 supported_groups 扩展与 ServerHello 的 key_share 扩展。混合组的 key_share 长度明显大于经典 X25519(ML-KEM-768 公钥约 1184 字节,加上 X25519 的 32 字节),这是抓包层面最直观的区分特征:
sudo tcpdump -i lo -w pq-kex.pcap 'tcp port 8443'
tshark -r pq-kex.pcap -Y 'tls.handshake.extensions_supported_group' \
-T fields -e tls.handshake.extensions_supported_group
抓包判读要点:ClientHello 中应同时出现混合组与 X25519 的组 ID;ServerHello 的 key_share 若为混合组,其长度字段应显著大于 32 字节。若 ServerHello 只回 X25519,说明服务端未启用混合组或客户端未提供,需要回到配置核对。
延迟与兼容性记录
握手延迟用 openssl s_client 的 -brief 输出或 time 命令做多次采样,取中位数以减少抖动。教学示例中可记录如下对照(数值为示例假设,需在实际环境复测):
| 客户端组配置 | 协商结果 | 握手耗时(示例) | 说明 |
|---|---|---|---|
| X25519MLKEM768:X25519 | X25519MLKEM768 | 约 2.1 ms | 混合组成功,key_share 更大 |
| X25519 | X25519 | 约 1.4 ms | 回退经典组,兼容性正常 |
| 仅 ML-KEM 组(不支持) | 握手失败 | — | 无共同组,验证失败路径 |
兼容性表现需覆盖三类客户端:支持混合组的新版 OpenSSL、仅支持经典组的老客户端、以及组配置不匹配的异常客户端。前两类应分别协商到混合组与 X25519,第三类应明确失败并给出可读错误,而不是静默降级到不安全配置。记录时同时保存 s_client 输出与 pcap 文件,便于后续复核。
X25519MLKEM768,抓包 ServerHello 的 key_share 长度与混合组一致,经典组客户端能正常回退,异常组客户端失败且错误信息可定位。三项同时满足才算部署验证完成。