必须替换底层密码库为gmssl/tongsuo等国密增强版并重新编译nginx,三者缺一不可;原生nginx仅调用openssl接口,不实现密码逻辑,标准openssl不识别sm2/sm3/sm4算法名,配置ssl_ciphers无效。

要让 Nginx 源码编译后支持国密算法(SM2/SM3/SM4),核心不是加模块或改配置,而是替换并绑定国密版密码库。原生 Nginx 和 OpenSSL 都不识别国密套件,必须从底层打通——这一步没做对,后续所有配置都会失效。
选一个能跑国密的密码库
不能用系统自带的 OpenSSL。必须选用以下任一国密增强版,并完成编译安装:
-
Tongsuo(推荐):蚂蚁开源,TLS 1.3 国密支持稳定,社区活跃,适配 Nginx 较好;安装后执行
tongsuo version和tongsuo list -cipher-algorithms | grep SM4确认识别 SM 算法 -
GMSSL:成熟早,文档全,政务项目常用;注意选 2.5.x 分支(非 gmssl3),安装前需运行
make install_dev,否则 Nginx 编译时找不到头文件 - openHiTLS:华为系,轻量模块化,适合嵌入式或定制场景;需确认其构建时启用了 SM2/SM3/SM4 支持
- OpenSSL-gm(中科院版):学术背景强,但生产环境建议先做稳定性验证
编译 Nginx 时显式绑定国密库路径
进入 Nginx 源码目录,configure 命令必须包含以下关键参数,缺一不可:
- --with-openssl=/path/to/your/gmssl-or-tongsuo:指向你安装好的国密库源码根目录(不是安装后的 /usr/local 下的路径,除非你明确用的是已安装的 dev 包)
-
--with-cc-opt="-I/path/to/include":指定头文件位置,例如
-I/usr/local/gmssl/include -
--with-ld-opt="-L/path/to/lib -lgmssl -lcrypto":链接时指定库路径和库名;若用 Tongsuo,对应为
-ltongsuo -lcrypto - 必须启用 --with-http_ssl_module,这是 TLS 支持的基础
常见错误:漏掉 --with-openssl=...,Nginx 就会 fallback 到系统 OpenSSL,编译成功但运行时仍不识别 SM2 密钥或 ECC-SM2-SM4-CBC-SM3 套件。
验证编译结果是否真正生效
编译安装完成后,别急着配证书,先做两件事确认底层链路通了:
- 运行
nginx -V 2>&1 | grep -i openssl,输出中应明确显示你指定的国密库路径,例如--with-openssl=/opt/gmssl - 启动 Nginx 后,用
openssl s_client -connect yourdomain:443 -tls1_2 -cipher 'ECC-SM2-SM4-CBC-SM3'测试握手;若返回SSL handshake has read 0 bytes and written 0 bytes或报no ciphers available,说明套件未加载成功,大概率是编译时链接出错或密码库本身未启用 NTLS/TLCP 支持
注意协议与指令的配套要求
国密 HTTPS 不是简单换套件,它依赖特定协议栈:
- 若用 Tongsuo,配置中必须启用
ssl_ntls on;,且ssl_protocols至少包含TLSv1.1(TLCP 协议基线) - 若用 GMSSL 编译的 Nginx,支持
ssl_certificate_enc和ssl_certificate_key_enc指令,用于双证书(签名证书 + 加密证书),这是国密标准要求 -
ssl_ciphers必须写国密专用套件,如"ECC-SM2-SM4-CBC-SM3:ECDHE-SM2-WITH-SM4-SM3",国际套件(如 AES、RSA)需显式排除,否则可能降级协商











