要构建完整的国密证书链,核心过程是通过根证书(Root CA)为中间证书(Intermediate CA)签名,再由中间证书为服务器签名证书和加密证书(即“双证书”)签名。整个流程就像是建立一套有层级、有规则的信任体系。
第一步:准备与规划
在动手之前,你需要确保完成以下几项准备:
安装GmSSL:推荐使用支持国密算法的 `GmSSL` 来代替标准OpenSSL。在Ubuntu/Debian系统下,可通过源码编译安装:
bash
sudo apt update && sudo apt install -y build-essential git cmake
git clone https://github.com/guanzhi/GmSSL.git
cd GmSSL && mkdir build && cd build
cmake .. && make && sudo make install
gmssl version # 验证是否安装成功
务必确保系统环境变量配置正确,使 `gmssl` 命令可以被直接调用。
创建目录结构**:为了方便管理,建议先建立一个工作目录。以下是一个国产密码PKI的典型目录结构:
~/gm-ca/
├── certs/ # 存放已签发的证书
├── crl/ # 存放证书吊销列表
├── newcerts/ # 存放由CA新签发的证书副本
├── private/ # 存放CA的私钥(权限需设置为700)
├── index.txt # 数据库文件,记录所有已签发证书
└── serial # 序列号文件,记录下一个证书的序列号
准备配置文件 (`gmssl-ca.conf`):这是整个流程中最关键的一步。国密证书的配置文件与标准OpenSSL相似,但包含国密特有的扩展项,你需要根据实际情况创建并填写。
第二步:构建根证书(信任之锚)
1. 生成根CA的SM2私钥:
bash
cd ~/gm-ca
gmssl ecparam -genkey -name sm2p256v1 -out private/root-ca.key
chmod 600 private/root-ca.key # 确保私钥安全
命令解释:`ecparam` 表示椭圆曲线参数操作,`-genkey` 生成密钥,`-name sm2p256v1` 指定使用SM2标准曲线。
2. 生成根CA的自签名证书:
bash
gmssl req -x509 -new -sm3 -days 730 -key private/root-ca.key \
-out certs/root-ca.crt -subj "/C=CN/ST=BJ/L=BJ/O=Example Root CA/CN=Example Root CA" \
-config gmssl-ca.conf -extensions v3_ca
命令解释:`req -x509` 表示生成一个自签名的X.509证书,`-sm3` 使用SM3作为摘要算法,`-days 730` 设置证书有效期为2年,`-extensions v3_ca` 确保该证书包含CA的基本约束(`basicConstraints=CA:TRUE`)。
第三步:签发中间证书(承上启下)
这是你的问题重点:使用根证书签发中间证书。
1. 生成中间CA的SM2私钥:
bash
gmssl ecparam -genkey -name sm2p256v1 -out private/intermediate-ca.key
【安全性提醒】:中间CA的私钥安全性仅次于根CA,建议存放在独立的、物理隔离的安全环境中,或使用硬件安全模块(HSM)进行保护。根CA的私钥则应为最高安全级别,建议仅在离线状态下使用。
2. 生成中间CA的证书签名请求(CSR):
bash
gmssl req -new -sm3 -key private/intermediate-ca.key \
-out intermediate-ca.csr -subj "/C=CN/ST=BJ/L=BJ/O=Example Intermediate CA/CN=Example Intermediate CA"
3. 根CA签发中间证书:
bash
gmssl ca -batch -md sm3 -extensions v3_ca -in intermediate-ca.csr \
-out certs/intermediate-ca.crt -days 365 -cert certs/root-ca.crt \
-keyfile private/root-ca.key -config gmssl-ca.conf
命令解释:`ca -batch` 表示以批处理模式(非交互)运行CA命令,`-md sm3` 指定摘要算法,`-extensions v3_ca` 应用CA扩展,`-cert` 和 `-keyfile` 指定了签发者(根CA)的证书和私钥。
第四步:签发服务器“双证书”(最终实体)
国密标准要求服务器必须拥有签名证书和加密证书,不可混用。
签名证书(用于身份验证)
1. 生成签名密钥和CSR:
bash
# 步骤1: 生成服务器签名私钥
gmssl ecparam -genkey -name sm2p256v1 -out server-sign.key
# 步骤2: 生成签名证书请求CSR
gmssl req -new -sm3 -key server-sign.key \
-out server-sign.csr -subj "/C=CN/ST=BJ/L=BJ/O=Example Server/CN=your-domain.com"
2. 使用中间CA签发签名证书:
bash
gmssl ca -batch -md sm3 -extensions server_cert -in server-sign.csr \
-out certs/server-sign.crt -days 365 -cert certs/intermediate-ca.crt \
-keyfile private/intermediate-ca.key -config gmssl-ca.conf
加密证书(用于加密会话密钥)
1. 生成加密密钥和CSR:
bash
# 步骤1: 生成服务器加密私钥(与签名私钥分开)
gmssl ecparam -genkey -name sm2p256v1 -out server-enc.key
# 步骤2: 生成加密证书请求CSR
gmssl req -new -sm3 -key server-enc.key \
-out server-enc.csr -subj "/C=CN/ST=BJ/L=BJ/O=Example Server/CN=your-domain.com"
```
【建议】:在国密标准中,签名密钥对通常由用户自己生成并保管,而加密密钥对可以委托给CA(密钥管理中心KMC)生成并安全分发,以支持密钥恢复。为简化流程,本示例采用了本地生成密钥的方式。
2. 使用中间CA签发加密证书:
bash
gmssl ca -batch -md sm3 -extensions enc_cert -in server-enc.csr \
-out certs/server-enc.crt -days 365 -cert certs/intermediate-ca.crt \
-keyfile private/intermediate-ca.key -config gmssl-ca.conf
第五步:组装与验证证书链
1. 制作完整的证书链文件: 最终服务器需要配置完整的证书链。通常,`fullchain.crt` 文件用于服务器配置,而 `chain.crt` 用于客户端验证。
bash
# 将服务器签名证书(或加密证书)和中间CA证书拼接,构成服务器配置所需的完整链
cat certs/server-sign.crt certs/intermediate-ca.crt > fullchain.crt
# 中间证书链(通常指从根证书到中间证书这一部分)
cat certs/intermediate-ca.crt certs/root-ca.crt > chain.crt
服务器配置实战**:在Nginx中配置国密支持时,你需要使用 `fullchain.crt` 作为 `ssl_certificate`,`server-sign.key` 和 `server-enc.key` 分别通过 `ssl_certificate_key` 和 `gmssl_certificate_key` 等指令指定。务必同时配置根证书和中间证书,否则客户端可能因找不到完整的信任链而报错。
2. 验证证书链: 使用命令检查证书是否按预期签发以及证书链的完整性。
bash
# 快速检查证书的颁发者和签名算法
gmssl x509 -in certs/intermediate-ca.crt -noout -issuer -subject -signature_algorithm
# 验证从服务器证书到根证书的完整信任链
# -CAfile 指定信任的根证书,-untrusted 指定中间证书
gmssl verify -CAfile certs/root-ca.crt -untrusted certs/intermediate-ca.crt certs/server-sign.crt
重要注意事项
双证书:国密标准要求为服务器同时配置签名证书和加密证书,这是实现TLCP国密协议的关键,不可使用同一张证书。
双栈部署(兼容性):考虑到全球浏览器支持情况,生产环境常采用“国密+国际”双证书方案,以兼容国密浏览器和主流浏览器。
算法合规性:从根证书、中间证书到服务器证书必须保持算法一致性,SM2或RSA,不可混用。同时确保证书的密钥用法(Key Usage)和扩展密钥用法(Extended Key Usage)正确设置了“数字签名”和“密钥加密”等属性。
证书链完整性:务必在服务器上配置完整的证书链(包含中间证书)。如果只配置服务器证书,某些浏览器可能无法验证其有效性。
安全性:根证书的私钥(`root-ca.key`)是信任体系的命脉,强烈建议在安全的、物理隔离的离线环境中保存和使用,完成证书签发后立即移出工作环境。
如果你在具体实施过程中(比如导出特定浏览器可用的格式,或处理证书吊销列表时)遇到难题,需要我提供更细致的脚本或排查思路,随时可以告诉我~