必须替换为国密增强版OpenSSL(如Tongsuo或GMSSL),编译定制Nginx,配置ssl_protocols与ssl_ciphers优先级,并按顺序加载SM2与RSA双证书,由客户端在ClientHello中自主协商算法栈。
要在 Nginx 中真正实现 RSA 与国密(SM2/SM3/SM4)双证书并行、协同工作,关键不是简单地把两个证书“都写上去”,而是构建一套基于客户端能力自动协商的双栈 TLS 服务。原生 Nginx + OpenSSL 完全不支持国密算法,必须先替换底层密码库,再配置协议与套件优先级,最后才涉及证书加载方式。
标准 OpenSSL 和最新 Nginx 编译后无法识别 SM2 公钥、SM3 哈希或 SM4 加密套件。实际部署中必须选用以下任一国密分支:
编译 Nginx 时需显式指定:--with-openssl=/path/to/tongsuo,而非系统自带 OpenSSL。验证是否生效:运行 tongsuo version 应显示含 sm2/sm3/sm4 的 cipher 列表;执行 openssl ecparam -list_curves | grep sm2 应有输出。
不需要开多个端口、也不需要重复 server 块。所有逻辑集中在同一个 server { } 中,靠协议与套件控制握手路径:
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3:TLCP(国密传输层协议)对应 TLS 1.1,但保留 1.2/1.3 可确保国际浏览器兼容ssl_ciphers "TLS_SM4_SM3:ECDHE-SM4-SM3:AES128-GCM-SHA256":国密套件置前,国际套件紧随其后,由客户端在 ClientHello 中声明支持的 cipher 决定走哪条链路ssl_prefer_server_ciphers on:强制服务端主导套件选择,避免客户端低优先级套件干扰协商结果根据合规要求和部署目标,主要有两类实践方式:
server_sign.crt/.key(身份认证与签名)和 server_enc.crt/.key(密钥交换)。Nginx 配置中使用 ssl_certificate_enc 和 ssl_certificate_key_enc 指令(仅国密版 Nginx 支持)ssl_certificate 和 ssl_certificate_key 各指定两次(先 SM2,后 RSA),Nginx 会按顺序尝试匹配客户端能力示例(SM2+RSA 共存写法):
ssl_certificate /path/to/sm2_cert.pem;
ssl_certificate_key /path/to/sm2_key.key;
ssl_certificate /path/to/rsa_cert.pem;
ssl_certificate_key /path/to/rsa_key.key;
证书不是随便拿两个 PEM 文件就能用,需满足特定结构和格式要求:
id-ecPublicKey (1.2.840.10045.2.1) + curve sm2p256v1
openssl ecparam -name sm2p256v1 -genkey -out server_sm2.key
openssl x509 -inform der -in cert.sm2 -out cert.pem