欢迎光临
我们一直在努力

Nginx 实现国密双证书配置(SM2 签名+加密)与 RSA 国际证书共存方案

Nginx 实现国密双证书配置(SM2 签名+加密)与 RSA 国际证书共存方案

背景介绍

随着国家对网络安全自主可控要求的不断提升,国产密码算法(简称“国密”)在金融、政务等关键领域的应用日益广泛。与此同时,为了兼容国际标准和外部系统对接,很多场景下需要同时支持 国际通用加密算法(如 RSA/ECC + AES + SHA256) 和 国密算法(SM2/SM4/SM3)。

实现银行国密双认证的配置: 问题我们会生成一个签发文件和密钥,把这个发给银行 ,然后银行会给一个key.txt 的加密文件,我们会使用我们生成的私钥去解密,然后会得到一个新的私钥,这个私钥就是拿去解密银行的文件。解密逻辑是这样的。

解密过程: 使用linux解密会报错,使用本地解密也会报错,尝试使用python 解密也会报错;

最后使用java解密成功了: 解密过程

## 解密流程总结

```
1. 解析key.txt的SM2EnvelopedKey结构

2. 提取SM2Cipher结构(XCoordinate, YCoordinate, HASH, CipherText

3. 按照GMT_0003.4规范SM2解密:
构造C1点
计算[dB]C1 = (x2, y2)
使用KDF(x2||y2)派生对称密钥
C2 ⊕ t = 对称密钥

4. 使用对称密钥SM4ECB解密私钥密文

5. 从key.txt提取C1点(公钥点)

6. 使用提取的公钥点组装私钥PEM文件
```

本文将详细介绍如何使用 Tongsuo(铜锁) —— 由蚂蚁集团开源并持续维护的 OpenSSL 分支,来配置 Nginx 同时支持 国际 SSL 证书 与 国密双证书(签名+加密),实现真正的“双栈”HTTPS 服务。

环境准备

  • 操作系统:Linux(如 CentOS 7/8、Ubuntu 20.04+)
  • Web 服务器:Nginx(需编译集成 Tongsuo)
  • 密码库:Tongsuo(原 BabaSSL,已更名为 Tongsuo)
  • 证书类型:
    • 国际证书:RSA 或 ECC 公钥证书(用于标准 TLS 握手)
    • 国密证书:两套 SM2 证书(一套用于签名 server_sign.crt,一套用于加密 server_enc.crt)

⚠️ 注意:国密 TLS 1.1(即 NTLS)协议要求使用 双证书机制,这是与国际标准最大的区别之一。

Nginx 配置详解

http {
# ... 其他通用配置 ...

server {
listen 443 ssl;
server_name sso.ch.shhang.com;

# ✅ 关键:开启国密支持(NTLS)
enable_ntls on;

# ==============================
# 国际证书(RSA 或 ECC)
# ==============================
ssl_certificate /opt/tongsuo/certs/rsa/server_sign.crt;
ssl_certificate_key /opt/tongsuo/certs/rsa/server_sign.key;

# 若使用 ECC 国际证书,可取消注释以下两行
# ssl_certificate /opt/tongsuo/certs/test_ecc.crt;
# ssl_certificate_key /opt/tongsuo/certs/test_ecc.key;

# ==============================
# 国密双证书(必须同时提供)
# ==============================
ssl_sign_certificate /opt/tongsuo/certs/sm2/server_sign.crt; # 签名证书
ssl_sign_certificate_key /opt/tongsuo/certs/sm2/server_sign.key; # 签名私钥

ssl_enc_certificate /opt/tongsuo/certs/sm2/server_enc.crt; # 加密证书
ssl_enc_certificate_key /opt/tongsuo/certs/sm2/server_enc.key; # 加密私钥

# ==============================
# 密码套件:混合支持国密与国际算法
# ==============================
ssl_ciphers "ECC-SM2-SM4-CBC-SM3:ECC-SM2-SM4-GCM-SM3:ECDHE-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-GCM-SM3:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!RC4:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS";

# 支持的协议版本(含 TLS 1.3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

# 默认响应类型(可根据实际业务调整)
default_type text/plain;
add_header "Content-Type" "text/html;charset=utf-8";

location / {
# 透传客户端真实 IP 和协议信息(重要!)
proxy_pass https://127.0.0.1:8443;
proxy_set_header Host $host;
proxy_set_header XRealIP $remote_addr;
proxy_set_header XForwardedFor $proxy_add_x_forwarded_for;
proxy_set_header XForwardedProto $scheme;
proxy_set_header XForwardedHost $host;
proxy_set_header XForwardedPort $server_port;

# 支持 WebSocket(可选,按需启用)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# 超时设置(建议根据后端性能调整)
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
}

关键配置项说明

配置项作用
enable_ntls on; 必须开启,启用国密 TLS(NTLS)协议支持
ssl_certificate / ssl_certificate_key 国际标准证书(RSA/ECC),用于非国密客户端连接
ssl_sign_certificate / ssl_sign_certificate_key 国密 签名证书,用于身份认证
ssl_enc_certificate / ssl_enc_certificate_key 国密 加密证书,用于密钥交换(国密要求分离)
ssl_ciphers 密码套件列表,国密套件必须放在前面,确保优先协商

为什么国密需要两个证书?

在国密 TLS 协议(GM/T 0024-2014)中,为增强安全性,签名与密钥交换使用不同的 SM2 密钥对,因此需要分别提供签名证书和加密证书。

客户端兼容性说明

  • 支持国密的客户端(如安装了国密浏览器插件、或使用 Tongsuo SDK 的 App):会优先使用 ECC-SM2-SM4-GCM-SM3 等国密套件完成握手。

  • 普通国际客户端(Chrome/Firefox/Safari 等):自动回落到 ECDHE-RSA-AES128-GCM-SHA256 等标准套件,无缝兼容。

  • 测试工具建议

    • 国密测试:使用 tongsuo s_client -ntls -connect your.domain:443
    • 国际测试:使用 openssl s_client -connect your.domain:443

常见问题排查

  • → 说明 Nginx 未正确编译 Tongsuo。请确认使用 Tongsuo 提供的 nginx 或自行编译时链接 Tongsuo 库。
  • 国密握手失败,但国际正常
    → 检查 ssl_sign_certificate 和 ssl_enc_certificate 是否都存在且有效;私钥是否匹配;证书是否由合法 CA 签发(或自签名但客户端信任)。
  • 密码套件顺序影响协商结果
    → 务必把国密套件写在最前面,否则可能被国际客户端“抢占”连接。
  • 总结

    以上是对接银行系统: 三方的软件应用又不支持国密双认证,那么我们就需要nginx代理一层,拦住然后加上国密双认证,还有加上国际认证,然后在透传代理下去。

    注意点: 和银行的签发文件解密过程。 以及验证国密使用 支持国密的浏览器。谷歌浏览器不支持国密。代理到资金应用使用了8443 端口,把默认的443端口留给代理的nginx。

    参考资料

    • Tongsuo 官方 GitHub
    • 《GM/T 0024-2014 SSL VPN 技术规范》
    • Nginx with Tongsuo 编译指南
    赞(0)
    未经允许不得转载:171主机测评 » Nginx 实现国密双证书配置(SM2 签名+加密)与 RSA 国际证书共存方案
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址