必须用gmssl替换openssl、重编译nginx并部署双证书结构三者缺一不可;原生nginx_http_ssl_module仅调用openssl接口,不实现密码逻辑,标准openssl不识别sm2/sm3/sm4算法名,配置ssl_ciphers无效。

原生 Nginx 的 http_ssl_module 无法直接支持国密 SM2/SM3/SM4——它只是调用 OpenSSL 的接口,自身不实现任何密码逻辑。所谓“配置模块启用国密”是常见误解。真正可行的路径只有一条:替换底层密码引擎、重编译 Nginx、严格部署双证书结构,三者缺一不可。
必须用国密版 OpenSSL 替换底层依赖
标准 OpenSSL(包括 1.1.1 或 3.0+ 默认版本)根本不识别 SM2 曲线 OID、SM3 摘要标识或 SM4 加密套件名。即使你在配置里写 ssl_ciphers ECDHE-SM2-SM4-SM3,OpenSSL 也会静默忽略或报错 unknown cipher。
- 选用已通过国家密码管理局认证的 GMSSL(推荐 v3.1+),编译时显式启用:
enable-sm2 enable-sm3 enable-sm4 - 安装路径统一设为
/usr/local/gmssl,避免与系统 OpenSSL 冲突 - 验证是否生效:
openssl version -a输出中必须含 GMSSL 字样;ldd $(which nginx) | grep ssl必须指向/usr/local/gmssl/lib/libssl.so
必须源码编译国密定制版 Nginx
Nginx 官方源码未适配 SM2 公钥格式(如 ASN.1 中的 id-sm2OID)、TLCP 协议扩展或国密证书用途字段校验。直接 patch 模块无效,必须从源头重建。
- 下载 Tengine(带
ngx_http_ssl_sm_module)或 openresty-gm 分支,二者已深度修改 SSL 握手栈 - configure 时强制指定:
--with-openssl=/usr/local/src/GmSSL --with-http_ssl_module - 手动检查
auto/lib/openssl/conf,确保头文件路径和库链接均指向 GMSSL 而非系统路径
必须采用双证书结构并正确配置指令
金融级合规要求签名与加密分离:一个证书用于身份认证与数字签名(Key Usage=digitalSignature),另一个专用于密钥封装与数据加解密(Key Usage=keyEncipherment)。两者私钥不可复用。
- 使用国密定制版 Nginx 特有指令:
ssl_certificate /path/to/sign.crt;ssl_certificate_key /path/to/sign.key;ssl_certificate_enc /path/to/encrypt.crt;ssl_certificate_key_enc /path/to/encrypt.key; - 协议必须设为
ssl_protocols GMv1;(TLCP 标准对应 TLS 1.1 语义),禁用TLSv1.2和TLSv1.3 - 密码套件仅保留国密组合,例如:
ssl_ciphers ECC-SM4-SM3:ECDHE-SM2-SM4-SM3;,并明确关闭所有国际套件
必须使用国密工具链生成和验证证书
CFCA、上海CA 等机构签发的 SM2 证书,其 SubjectPublicKeyInfo 字段必须包含标准 OID 1.2.156.10197.1.301(id-sm2),否则 Nginx 加载即失败。
- 私钥必须用 GMSSL 工具生成:
gmssl genpkey -algorithm sm2 -out server_sign.key - 证书请求和签发全程使用
gmssl req和gmssl x509,不可混用 OpenSSL 命令 - 验证证书用途:
gmssl x509 -in server_sign.crt -text -noout | grep "Key Usage",确认为 digitalSignature











