在原生Nginx环境下配置SM2+RSA双证书,核心思路是:使用支持国密算法的Nginx衍生版或重新编译Nginx,因为官方原版Nginx+OpenSSL不支持国密算法。

目前主流的方案有以下几种:

方案一:使用Angie(Nginx衍生版)+  Tongsuo(铜锁)  ——  Angie已内置对国密的支持,配置最简单,可直接替代Nginx

  方案二:使用Tengine  +  Tongsuo  ——  淘宝开源的Nginx衍生版,同样适配了国密

  方案三:自行编译国密版Nginx  ——  使用GmSSL或Tongsuo重新编译Nginx

方案一:Angie  +  Tongsuo(推荐)

1.  安装依赖

```bash

yum  -y  install  wget  gcc  gcc-c++  make  pcre  pcre-devel  zlib-devel  perl

```

2.  下载并编译安装

```bash

#  下载Tongsuo

wget  -c  https://github.com/BabaSSL/BabaSSL/archive/refs/tags/8.2.1.tar.gz

tar  -zxvf  Tongsuo-8.2.1.tar.gz

#  下载Angie

curl  -O  https://download.angie.software/files/angie-1.8.1.tar.gz

tar  -xpf  angie-1.8.1.tar.gz

cd  angie-1.8.1

#  编译安装(关键:关联Tongsuo并启用ntls)

./configure  \

        --prefix=/usr/local/angie  \

        --with-openssl=../Tongsuo-8.2.1  \

        --with-openssl-opt=enable-ntls  \

        --with-ntls  \

        --with-http_ssl_module

make  -j

make  install

```

3.  配置双证书

编辑  `/usr/local/angie/conf/nginx.conf`:


```nginx

server  {

        listen  443  ssl;

        server_name  yourdomain.com;

        #  开启国密TLS支持

        ssl_ntls  on;                                                    #  Tongsuo必须使用ssl_ntls

        #  SM2双证书:签名证书  +  加密证书(顺序:先签名后加密)

        ssl_certificate  sign.crt  enc.crt;

        ssl_certificate_key  sign.key  enc.key;

        #  RSA兼容证书

        ssl_certificate  rsa/server_rsa.pem;

        ssl_certificate_key  rsa/server_rsa.key;

        #  国密套件  +  RSA兼容套件

        ssl_ciphers  ECC-SM2-SM4-CBC-SM3:ECDHE-SM2-WITH-SM4-SM3:ECDHE-RSA-AES128-GCM-SHA256:...;

        ssl_protocols  TLSv1  TLSv1.1  TLSv1.2  TLSv1.3;

        ssl_prefer_server_ciphers  on;


        location  /  {

                root  html;

                index  index.html  index.htm;

        }

}

```

4.  重启服务

```bash

cd  /usr/local/angie/sbin

./angie  -s  reload

```

方案二:自行编译国密版Nginx

如果希望继续使用官方Nginx,则需要用国密版OpenSSL重新编译:

```bash

#  下载国密版OpenSSL(GmSSL或Tongsuo)

wget  https://github.com/guanzhi/GmSSL/archive/master.zip

unzip  master.zip

#  下载Nginx源码

wget  http://nginx.org/download/nginx-1.18.0.tar.gz

tar  -zxvf  nginx-1.18.0.tar.gz

cd  nginx-1.18.0

#  编译(指定国密版OpenSSL路径)

./configure  \

        --prefix=/usr/local/nginx  \

        --with-http_ssl_module  \

        --with-openssl=/path/to/GmSSL-master  \

        --with-cc-opt="-I/path/to/GmSSL-master/include"  \

        --with-ld-opt="-lm"

make  &&  make  install

```

配置方式与方案一类似,但需注意部分国密版Nginx使用  `enable_ntls`  而非  `ssl_ntls`(取决于具体版本)。

证书文件说明

SM2国密证书采用双证书模式,包含两套密钥对:

文件      说明  

`sign.crt`  /  `sign.key`      SM2签名证书及私钥  

  `enc.crt`  /  `enc.key`      SM2加密证书及私钥  

  `rsa.crt`  /  `rsa.key`      RSA国际标准证书及私钥  

注意:私钥必须为未加密的PEM格式。配置时先配置签名证书,再配置加密证书,签名和加密证书的私钥key为同一个。

验证方法

1.  配置语法检查:

      ```bash

      /usr/local/nginx/sbin/nginx  -t

      ```

2.  国密浏览器测试:使用红莲花浏览器、密信浏览器或奇安信浏览器(需开启“国密SSL通信”开关)访问站点

3.  命令行测试(需使用Tongsuo版的openssl):

      ```bash

      openssl  s_client  -connect  yourdomain.com:443  -tls1_2  -cipher  ECC-SM4-CBC-SM3

      ```

关键注意事项

1.  原生Nginx不支持国密,必须使用国密版OpenSSL(Tongsuo/GmSSL)重新编译,或直接使用Angie/Tengine等国密衍生版

2.  SM2需要签名和加密两套证书,二合一的证书通常无法正常工作

3.  配置生效后,服务器会根据客户端能力**自动切换**:国密浏览器走SM2,普通浏览器走RSA