跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

利用 Nginx 模块实现国产 SM 系列算法支持:金融级 Web 网关合规化建设全流程教程

Nginx官方主线不支持国密算法,必须替换底层OpenSSL为gmssl等国密分支,并编译集成nginx_gm模块;需验证nginx -V中OpenSSL路径指向gmssl、其version含GMSSL字样,再配置ssl_ciphers为ECDHE-SM2-SM4-CBC-SM3等国密套件,且证书、私钥、CA链、OCSP响应均须全程SM2签名,否则握手失败。 目前 Nginx 官方主线不支持 SM2/SM3/SM4,直接编译或配置
ssl_protocols
或
ssl_ciphers
无法启用国密算法;必须依赖第三方模块(如
nginx_gm
)并替换底层 OpenSSL 为支持国密的分支(如
gmssl
或
openssl-gm
)。 确认底层 OpenSSL 是否已替换为国密支持版本 很多团队卡在第一步:以为装了国密模块就万事大吉,结果
nginx -V
显示仍链接着系统默认 OpenSSL(
OpenSSL 1.1.1w
或
3.0.x
),这类版本原生不认
SM2
密钥或
SM4-CBC
密码套件。 运行
nginx -V 2>&1 | grep -i openssl
,检查输出中的
built with OpenSSL
路径是否指向你编译安装的
gmssl
(例如
/usr/local/gmssl
) 进入该路径,执行
bin/openssl version -a
,确认输出含
GMSSL
字样且版本号 ≥
3.1.1
若显示
OpenSSL 1.1.1
或无
GMSSL
,说明 Nginx 编译时未指定
--with-openssl=
指向国密 OpenSSL 源码,需重编译 编译 Nginx 时正确加载 nginx _gm 模块
nginx_gm
是目前最稳定的国密模块(维护活跃、适配 Nginx 1.18–1.25),但它不是
--add-module
单步能搞定的——它强依赖 GMSSL 的头文件和符号导出,且部分版本需 patch Nginx 源码。 下载与你的 Nginx 版本匹配的
nginx_gm
分支(如 Nginx 1.22 → 用
nginx_gm
的
v1.22
tag) 编译前先在 GMSSL 源码根目录执行
make install_dev
(否则
./configure
会报
gmssl.h: No such file
)
./configure
必须显式指定:
--with-openssl=/path/to/gmssl/src --add-module=/path/to/nginx_gm
若遇到
undefined reference to `EVP_sm4_cbc'
,说明链接时未带
-lgmssl
,需修改
objs/Makefile
中
NGX_RPATH
和
LIBS
行补全 配置 server 块启用 SM2+SM4 双向认证 国密合规不止是“能用 SM4 加密”,金融场景要求 TLS 层级的双向认证(mTLS),且证书链、密钥格式、密码套件必须严格匹配 GMSSL 规范。 Nginx 在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。 下载 私钥必须为 SM2 格式(PEM 中含
-----BEGIN EC PRIVATE KEY-----
且曲线为
sm2p256v1
),不可用 RSA 私钥混用 证书需由国密 CA 签发,且
subjectAltName
必须包含域名,否则现代浏览器拒绝建立连接 关键配置项:
ssl_certificate /etc/nginx/certs/server.crt; ssl_certificate_key /etc/nginx/certs/server.key; ssl_client_certificate /etc/nginx/certs/ca.crt; ssl_verify_client on; ssl_protocols TLSv1.2; ssl_ciphers ECDHE-SM2-SM4-CBC-SM3:SM2-SM4-CBC-SM3;
注意:
ssl_ciphers
中不能混入非国密套件(如
ECDHE-RSA-AES256-GCM-SHA384
),否则协商失败返回
no suitable cipher
验证连接是否真正走国密协议栈 浏览器地址栏显示锁图标 ≠ 国密生效;Chrome/Firefox 默认禁用国密套件,必须用国密浏览器(如红莲花、零信)或命令行工具验证。 用
openssl s_client -connect example.com:443 -cipher 'SM2-SM4-CBC-SM3' -tls1_2
,成功时输出应含
New, TLSv1.2, Cipher is SM2-SM4-CBC-SM3
抓包看 ClientHello 的
cipher_suites
字段是否含
0xc0,0x9f
(即
SM2-SM4-CBC-SM3
的 IANA ID) Nginx error log 出现
SSL_do_handshake() failed (SSL:) ... no ciphers available
,大概率是
ssl_ciphers
写错、证书非 SM2、或客户端不支持 别忽略 OCSP Stapling:国密证书的 OCSP 响应也需用 SM2 签名,否则
ssl_stapling on
会导致 handshake hang 真正的难点不在编译或配置,而在于整条信任链的国产化闭环:从 CA 根证书、中间证书、终端证书的签发算法,到 OCSP 响应签名、CRL 分发点证书,全部必须是 SM2;漏掉任意一环,TLS 握手就在某个环节静默失败。

相关文章