Nginx原生不支持SM2/SM3/SM4,必须替换为GMSSL或TASSL等国密增强版OpenSSL并重新编译Nginx,再配置SM2双证书、TLCP协议及国密套件(如ECDHE-SM2-SM4-CBC-SM3)方可实现合规国密TLS握手。
在 Nginx 中直接原生支持 SM2/SM3/SM4 国密算法并不可行,因为官方 Nginx 依赖 OpenSSL(截至 3.0 版本仍不支持国密套件),而 OpenSSL 官方主线至今未集成 SM2/SM3/SM4。要实现国密合规落地,核心路径是:**替换底层密码库为支持国密的 OpenSSL 兼容分支(如 gmssl 或 tassl),再基于其重新编译 Nginx,并配置国密证书与 TLS 协议栈**。
这是整个方案的前提。推荐两个成熟分支:
部署时需卸载系统默认 OpenSSL 开发包,下载对应分支源码,启用国密选项编译安装(例如 GMSSL 编译时加 --enable-sm2 --enable-sm3 --enable-sm4),确保 pkg-config openssl --modversion 返回的是 GMSSL 版本号。
Nginx 本身不内置 TLS 实现,而是通过 configure 阶段链接 OpenSSL 库。需确保:
./configure --with-openssl=/path/to/gmssl --with-openssl-opt=enable-sm2(部分版本需额外加 --with-http_ssl_module);ldd objs/nginx | grep ssl 应指向 GMSSL 的 libssl.so;nginx -V 2>&1 | grep -i sm 或用 openssl s_client -connect localhost:443 -cipher "SM2-SM4-SM3" 测试握手能力。国密 HTTPS 要求整条信任链均使用 SM2 公钥和 SM3 摘要:
ssl_certificate 文件(PEM 格式,先服务端证书,再中间证书);-----BEGIN EC PRIVATE KEY----- 或 GMSSL 特有的 -----BEGIN SM2 PRIVATE KEY----- 开头),且无加密口令(Nginx 不支持解密带密码的国密私钥)。示例配置片段:
server { listen 443 ssl; ssl_certificate /etc/nginx/ssl/gm_server.crt; # SM2 证书 + 中间证书 ssl_certificate_key /etc/nginx/ssl/gm_server.key; # SM2 私钥 ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-SM2-SM4-CBC-SM3:SM2-SM4-CBC-SM3; ssl_prefer_server_ciphers on;}
纯国密 TLS(仅 SM2/SM4/SM3)仅被国产浏览器(如 360 安全浏览器国密版、红莲花浏览器)及部分政务客户端支持。生产环境建议采用双证书+双协议策略:
ssl_certificate_by_lua*(需集成 ngx_lua)或上游负载层(如自研 TLS 分流网关)根据 ClientHello 中的 cipher suites 列表识别国密能力,动态选择证书;ssl.client_hello():ciphers() 是否含 0x00, 0x9A(SM2-SM4-SM3 的 IANA 注册值)来切换证书。