验证国密双证书在nginx中协同工作,需分四层:确认nginx链接国密openssl(如tongsuo路径)、检查签名/加密证书格式与用途合规(sm2公钥、keyencipherment等)、用gmssl/tongsuo工具发起tlcp或国密tls1.3握手测试、开启debug日志观察协商套件及失败原因。

测试国密双证书在 Nginx 中是否协同工作,核心是验证“签名证书 + 加密证书”能否被正确加载、解析,并在 TLS 握手阶段按 TLCP 或双栈模式被客户端成功协商。这不是简单检查配置语法,而是分层验证:从服务端基础能力、证书链有效性,到真实客户端握手行为。
确认 Nginx 已正确链接国密 OpenSSL 并识别 SM2
这是前提,否则后续所有测试都无意义:
- 运行 nginx -V 2>&1 | grep -i openssl,输出中必须包含你安装的国密 OpenSSL 路径(如 /usr/local/tongsuo),而非系统默认路径(如 /usr/lib64/libssl.so)
- 执行 tongsuo version 或 gmssl version,确认输出含 sm2、sm3、sm4 字样
- 运行 openssl ecparam -list_curves | grep sm2,应返回 sm2p256v1 —— 表明底层密码库已启用 SM2 曲线支持
检查证书与私钥格式及用途是否合规
国密双证书对文件内容有严格要求,仅文件存在不等于可用:
- 用 openssl x509 -in server_sign.crt -text -noout | grep "Subject Public Key Info" 确认签名证书公钥类型为 id-ecPublicKey, SM2
- 用 openssl x509 -in server_enc.crt -text -noout | grep "Key Usage" 检查加密证书是否含 keyEncipherment(而非 digitalSignature)
- 用 openssl ec -in server_sign.key -check -noout 验证签名私钥为合法 SM2 格式;同理检查加密私钥
- 确保 ssl_certificate_enc 和 ssl_certificate_key_enc 指令在配置中已启用(原生 Nginx 不识别,仅国密定制版支持)
使用国密客户端工具发起真实握手测试
浏览器或 curl 无法替代专用工具,必须用支持 TLCP/国密套件的命令行工具:
- 用 gmssl s_client -connect example.com:443 -tls1_1 -cipher ECC-SM4-SM3(TLCP 模式):若返回 Verify return code: 0 (ok) 且 Server certificate 中显示 SM2 公钥,则签名+加密双证链完整
- 用 tongsuo s_client -connect example.com:443 -ciphersuites TLS_SM4_SM3:ECDHE-SM4-SM3(TLS 1.3 国密模式):观察是否完成 ECDHE-SM4-GCM-SM3 握手,并打印出 Server Temp Key: sm2p256v1
- 若返回 ssl3_get_server_certificate: certificate verify failed,说明中间 CA 缺失或签名证书未包含完整链(需合并为 fullchain.pem)
观察 Nginx 日志中的 TLS 协商细节
开启详细 SSL 日志可定位协商失败环节:
- 在 Nginx 配置中添加:error_log /var/log/nginx/ssl_debug.log debug;(需编译时启用 --with-debug)
- 重启后访问,查看日志中是否出现 "SSL_do_handshake() failed" 或 "no shared cipher"
- 成功协商时,日志会明确记录使用的套件,例如:"SSL: using cipher list 'ECC-SM4-SM3:ECDHE-SM4-SM3'
- 若日志中反复出现 "client offered no suitable cipher",说明客户端不支持所配套件,或服务端未启用对应协议(如 TLCP 必须设 ssl_protocols TLSv1.1)











