🛠 密改技术方案

常见系统的国密改造技术方案与配置指南

Nginx 国密 SSL/TLS 双证书方案

通过 GmSSL 编译支持国密的 Nginx,配置国密双证书实现 HTTPS 密改合规。

1. 编译 GmSSL

git clone https://github.com/guanzhi/GmSSL.git
cd GmSSL
make && sudo make install
sudo ldconfig

2. 编译支持国密的 Nginx

wget https://nginx.org/download/nginx-1.24.0.tar.gz
tar zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0

./configure \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-openssl=/path/to/GmSSL \
  --with-cc-opt="-I/usr/local/gmssl/include" \
  --with-ld-opt="-L/usr/local/gmssl/lib"

make && sudo make install

3. 生成国密双证书

# 生成 SM2 签名证书
gmssl certgen -C CN -O "My Company" -CN "example.com" \
  -key sm2_sign.key -out sm2_sign.crt

# 生成 SM2 加密证书
gmssl certgen -C CN -O "My Company" -CN "example.com" \
  -key sm2_enc.key -out sm2_enc.crt

4. Nginx 配置

server {
    listen 443 ssl;
    server_name example.com;

    # 国密签名证书
    ssl_certificate     /etc/nginx/ssl/sm2_sign.crt;
    ssl_certificate_key /etc/nginx/ssl/sm2_sign.key;

    # 国密加密证书
    ssl_certificate_enc     /etc/nginx/ssl/sm2_enc.crt;
    ssl_certificate_key_enc /etc/nginx/ssl/sm2_enc.key;

    # 国际证书(兼容非国密客户端)
    ssl_certificate     /etc/nginx/ssl/rsa.crt;
    ssl_certificate_key /etc/nginx/ssl/rsa.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-SM2-WITH-SM4-SM3:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://backend;
    }
}

5. 验证

# 使用 GmSSL 客户端测试
gmssl s_client -connect example.com:443 \
  -cipher ECDHE-SM2-WITH-SM4-SM3

# 检查国密套件是否生效
gmssl s_client -connect example.com:443 \
  -cipher ECDHE-SM2-WITH-SM4-SM3 2>&1 | grep "Cipher"

OpenSSL 国密改造方案

使用 GmSSL 替代 OpenSSL,或使用支持国密的 OpenSSL 分支。

方案一:GmSSL 替代

# 安装 GmSSL(兼容 OpenSSL 接口)
git clone https://github.com/guanzhi/GmSSL.git
cd GmSSL && make && sudo make install

# 验证 SM2 支持
gmssl sm2keygen -out sm2.key
gmssl sm2 -sign -in msg.txt -key sm2.key -out sig.dat
gmssl sm2 -verify -in msg.txt -sig sig.dat -pubout sm2.pub

方案二:OpenSSL 3.x + 国密 Provider

# 安装 OpenSSL 3.x
wget https://www.openssl.org/source/openssl-3.2.0.tar.gz
tar zxvf openssl-3.2.0.tar.gz
cd openssl-3.2.0
./config --prefix=/usr/local/openssl3
make && sudo make install

# 安装 Tongsuo(铜锁)国密 Provider
git clone https://github.com/Tongsuo-Project/Tongsuo.git
cd Tongsuo
./config --prefix=/usr/local/tongsuo
make && sudo make install

# 配置 openssl.cnf 加载国密 Provider
# [provider_sect]
# gmprov = gmprov_sect
# [gmprov_sect]
# provider = gmprov

SM2 证书生成

# 生成 SM2 密钥对
gmssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:sm2p256v1 \
  -out sm2.key

# 生成 CSR
gmssl req -new -key sm2.key -out sm2.csr \
  -subj "/C=CN/O=My Company/CN=example.com"

# 自签名证书
gmssl x509 -req -in sm2.csr -signkey sm2.key \
  -out sm2.crt -days 365

MySQL 国密改造方案

MySQL 国密改造主要涉及 TLS 连接加密和数据传输加密。

1. 生成国密证书

# 生成 CA 证书
gmssl certgen -C CN -O "MySQL CA" -CN "MySQL CA" \
  -key mysql_ca.key -out mysql_ca.crt

# 生成服务器证书
gmssl certgen -C CN -O "MySQL Server" -CN "db.example.com" \
  -key mysql_server.key -out mysql_server.crt \
  -CA mysql_ca.crt -CAkey mysql_ca.key

# 生成客户端证书
gmssl certgen -C CN -O "MySQL Client" -CN "mysql_client" \
  -key mysql_client.key -out mysql_client.crt \
  -CA mysql_ca.crt -CAkey mysql_ca.key

2. MySQL 配置

# my.cnf
[mysqld]
# SSL/TLS 配置
ssl-ca=/etc/mysql/ssl/mysql_ca.crt
ssl-cert=/etc/mysql/ssl/mysql_server.crt
ssl-key=/etc/mysql/ssl/mysql_server.key

# 强制 SSL
require_secure_transport=ON

# TLS 版本
tls_version=TLSv1.2,TLSv1.3

3. 客户端连接

mysql --ssl-ca=mysql_ca.crt \
      --ssl-cert=mysql_client.crt \
      --ssl-key=mysql_client.key \
      -h db.example.com -u user -p

4. 注意事项

  • MySQL 8.0.30+ 原生支持国密 SSL
  • 低版本需要使用 GmSSL 编译的 MySQL
  • 国密 SSL 性能开销约 5-15%,需评估影响

应用系统国密改造方案

应用层国密改造涉及数字签名、数据加密、身份认证等。

1. 数字签名改造

// Java - 使用 BouncyCastle 国密库
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
import java.security.Signature;

Security.addProvider(new BouncyCastleProvider());

// SM2 签名
Signature sig = Signature.getInstance("SM3withSM2", "BC");
sig.initSign(privateKey);
sig.update(data);
byte[] signature = sig.sign();

// SM2 验签
sig.initVerify(publicKey);
sig.update(data);
boolean valid = sig.verify(signature);

2. 数据加密改造

// SM4 加密(CBC 模式)
Cipher cipher = Cipher.getInstance("SM4/CBC/PKBC5Padding", "BC");
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "SM4");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(plaintext);

3. 哈希改造

// SM3 哈希
MessageDigest md = MessageDigest.getInstance("SM3", "BC");
byte[] hash = md.digest(data);
String hex = Hex.toHexString(hash);

4. 改造检查清单

  • 所有数字签名使用 SM2-with-SM3
  • 对称加密使用 SM4(CBC/ECB)
  • 哈希计算使用 SM3
  • 随机数生成使用国密安全随机数
  • 密钥管理使用国密算法保护
  • TLS 连接支持国密套件
  • 数字证书使用 SM2 证书