正确写法分下面几点说明:
一、核心结论:`ECDHE-SM2-SM4-SM3` 并非合法套件名
在Nginx配置中写入 `ssl_ciphers ECDHE-SM2-SM4-SM3;` 无效,Nginx将无法识别该套件名称,第三方依赖的 OpenSSL 密码库也不支持该拼写。
二、前提条件:原生 Nginx 不支持国密
原生 Nginx(从 nginx.org 下载的标准版本)依赖 OpenSSL 1.1.1 及更早版本,这些版本完全不识别 SM 系列算法标识,因此无法通过简单配置开启国密。
在编写任何 Nginx 国密配置之前,必须先解决环境准备问题:
安装或编译支持国密的 Nginx:可使用 GMSSL 3.1.1+ 替换 OpenSSL 并重新编译 Nginx,或使用 Tengine + gmssl 补丁、openresty-gm、Tongsuo(铜锁)等国内已成熟落地的方案。
验证编译后的 Nginx 是否正确链接了国密版 OpenSSL:执行 `nginx -V 2>&1 | grep -o 'OpenSSL [^ ]*'`,应显示 `OpenSSL 3.1.1-gm` 类似字样。
三、正确配置写法对比
版本/实现 加密套件写法规格 示例
GMSSL / Wosign SM2 模块 套件名格式为 "`算法-算法-算法`" 连字符风格 | `ECDHE-SM4-SM3`, `SM4-SM3`, `ECC-SM2-WITH-SM4-SM3` |
Tongsuo(铜锁)/ BabaSSL 套件名格式为 "`ECC-SM2-WITH-SM4-XX`" 风格 | `ECC-SM2-WITH-SM4-GCM-SM3`
TLS 标准命名风格(GMSSL 3.x+ 支持) 套件名以 "`TLS_`" 开头,下划线分隔 `TLS_SM4_GCM_SM3`, `TLS_SM4_SM3`, `TLS_SM4_SHA256`
部分双栈配置风格 简写格式,不同实现可能支持 `GM-SM2-SM4-SM3`
推荐配置写法(按使用场景分类)
场景一:使用 GMSSL 编译的 Nginx(含 GMSSL 的 OpenSSL 分支)
nginx
ssl_ciphers "ECDHE-SM4-SM3:SM4-SM3:TLS_SM4_SM3:TLS_SM4_SHA256";
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
说明:冒号 `:` 分隔多个套件,套件顺序影响协商优先级。建议将国密套件放在前面(优先协商国密通道),若与终端客户端协商失败可自动回退(fallback)。
场景二:使用 Tongsuo(铜锁)编译的 Nginx(原 BabaSSL)
nginx
enable_ntls on; # 关键:开启国密 NTLS 支持
ssl_ciphers "ECC-SM2-WITH-SM4-GCM-SM3:ECC-SM2-WITH-SM4-CBC-SM3";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 国密 TLCP(NTLS)基于 TLS 1.1
说明:Tongsuo 要求显式启用 `enable_ntls on;`,表示启用国密 NTLS(GM/T 0024-2014 定义的国密 TLS 变体),国密套件名称以 `ECC-SM2-WITH-SM4-*` 格式呈现。
国密双证书共存场景完整参考配置(RSA + SM2 双栈)
常见的面向金融、政务等合规要求的部署方案:
nginx
http {
server {
listen 443 ssl;
server_name your.example.com;
# 国际证书(RSA / ECC)用于通用客户端
ssl_certificate /path/to/rsa/server_rsa.crt;
ssl_certificate_key /path/to/rsa/server_rsa.key;
# 国密证书
ssl_certificate /path/to/sm2/sm2_sign.crt; # SM2 签名证书
ssl_certificate_key /path/to/sm2/sm2_sign.key; # SM2 私钥
# 国密 NTLS 开关(Tongsuo / 部分国密定制 Nginx 支持)
enable_ntls on;
# 同时包含国密和国际通用加密套件
ssl_ciphers "ECC-SM2-WITH-SM4-GCM-SM3:"
"ECDHE-ECDSA-AES128-GCM-SHA256:"
"ECDHE-RSA-AES128-GCM-SHA256";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
}
}
说明:国密 TLS 协议(即 TLCP 或 NTLS)基于 TLS 1.1 框架,推荐在配置中包含 TLSv1.1 以满足最广范围兼容日;国际客户端(Chrome/Firefox/Safari 等)可自动回落到 `ECDHE-ECDSA` / `ECDHE-RSA` 等国际套件。
四、验证与错误排查
1. 验证配置语法
每次修改配置文件后,先执行测试:
bash
# 测试配置文件语法
sudo nginx -t
2. 验证国密握手是否成功(推荐 gmssl 工具)
使用支持国密的测试客户端:
bash
gmssl s_client -connect your.domain:443 -cipher "ECC-SM2-SM4-CBC-SM3"
成功时连接日志中会显示类似 `Protocol: GMSSL` 和 `Cipher: ECC-SM2-SM4-CBC-SM3 / TLS_SM4_GCM_SM3` 等字样。
失败时常见错误为 `SSL_do_handshake() failed` 或 `handshake failure`。
3. 常见错误场景与排查思路
现象 常见原因 解决方案
`nginx -t` 通过,但浏览器握手失败 国密依赖的 OpenSSL 库不支持国密算法。需重新编译替换或切换国密分支(在支持国密的定制 Nginx 上重试) 检查 `nginx -V` 的输出,确认链接的是 GMSSL 或 Tongsuo 等国密版 OpenSSL,而不是默认 OpenSSL(例如 `OpenSSL 1.1.1q` 为不支持)
`ssl_ciphers ...` 启动时报错 `unknown cipher` 套件名拼写错误+底层 OpenSSL 完全不支持 SM 相关名称 确认 Nginx 底层已替换为国密版 OpenSSL,并使用该版本文档中列出的正确套件名
国密握手成功,但国际浏览器无法访问 配置中仅包含国密套件但未同时配置国际套件,或 `enable_ntls` 可能限制了协商范围 在 `ssl_ciphers` 中同时保留国密套件和国际通用套件(如 `ECDHE-ECDSA-AES128-GCM-SHA256`);确认 `enable_ntls on` 不影响国际 TLS 协商(一般为开关 GM/T 通道,不破坏标准 TLS)
证书链验证失败 SM2 证书的 OID 不符合标准,或 Nginx 源码未完全适配 SM2 公钥解析路径 确保通过 GMSSL 专有的 `gmssl genpkey -algorithm sm2 -out sm2.key` 等工具生成证书,证书中应明确含有 `Subject Public Key Info: sm2` 字段
五、补充说明
`ECDHE-SM2-SM4-SM3` 这类套件写法之所以经常出现在网络搜索或文档中,通常是「类似 `ECDHE-ECDSA-AES128-GCM-SHA256` 国际套件命名规则的直觉类比」,但实际上没有主流国密 OpenSSL 分支(GMSSL、Tongsuo)支持该拼写。实践中应严格参考你所采用的具体国密 Nginx 分支(GMSSL、Tongsuo、Tengine-gm、openresty-gm、Wosign wotrus_ssl 等)的官方文档和 `nginx -V` 中列出的可用套件名来编写。