国密证书链不能简单拼接,必须严格按TLCP和GM/T 0024标准分离构建签名链(含digitalSignature)与加密链(含keyEncipherment),各自完整、物理隔离、顺序正确,并通过国密OpenSSL验证及Nginx双指令加载。

国密证书链不是简单拼接就能用的,它必须严格遵循 TLCP 协议和 GM/T 0024 标准,尤其在证书层级、用途分离和格式兼容性上都有硬性要求。普通 RSA 证书链那一套“根+中间+域名”直接 cat 合并的方式,在国密场景下大概率导致握手失败或密评不通过。
国密证书链必须按双证书结构分别构建
国密不接受单证书复用,签名证书链和加密证书链必须物理隔离、独立签发、各自完整:
- 签名证书链(server_sign_bundle.crt):包含域名签名证书 + 对应国密中间 CA + 国密根 CA,且整条链中所有证书的 Key Usage 必须明确包含 digitalSignature,不能含 keyEncipherment
- 加密证书链(server_enc_bundle.crt):包含域名加密证书 + 对应国密中间 CA + 国密根 CA,Key Usage 必须明确含 keyEncipherment,不能含 digitalSignature
- 两套链不能混用中间证书;若 CA 提供的是通用中间证书(同时含两种 Key Usage),需确认其是否被国密浏览器和 Tongsuo/GMSSL 实际信任——多数合规环境要求中间证书也做用途分离
证书链完整性验证不能只看文件是否存在
光把 .crt 文件放对路径还不够,必须验证链是否可被国密 OpenSSL 正确解析并信任:
- 用
/usr/local/tongsuo/bin/openssl verify -CAfile /path/to/root_sm2.crt -untrusted /path/to/intermediate_sm2.crt server_sign.crt检查签名证书链是否可信 - 同样方式验证加密证书链,注意要换用加密证书对应的中间和根证书(即使文件名相同,也可能因扩展字段不同而不互通)
- 执行
/usr/local/gmssl/bin/gmssl x509 -in server_sign_bundle.crt -text -noout | grep -A2 "X509v3 Key Usage",确认输出中只出现 digitalSignature,且无解析错误
PEM 格式与编码细节极易出错
国密证书链对 PEM 封装格式敏感,常见问题包括:
- 证书文件末尾多空行、缺换行符,或混入不可见 Unicode 字符,会导致 Nginx 启动时报
SSL_CTX_use_certificate_chain_file() failed - 中间证书顺序必须是“域名证书 → 中间证书 → 根证书”,反序或漏掉任一环,国密客户端握手时会提示 “unknown ca”
- 不能将 SM2 证书与 RSA 证书混在一个 bundle 文件里;Nginx 加载时会静默跳过无法识别的证书块
- 使用
openssl x509 -in cert.pem -noout -text查看证书 OID,签名证书 SubjectPublicKeyInfo 中的 curve 应为1.2.156.10197.1.301(SM2),而非 secp256r1 或其他
Nginx 配置中证书链指令必须匹配双证书模型
标准 ssl_certificate 指令仅能加载一套链路,国密双证书需依赖增强版 Nginx 的扩展指令:
- 使用 Tongsuo 编译的 Nginx:用
ssl_certificate_sm2_sign指向签名证书链,ssl_certificate_sm2_enc指向加密证书链 - 使用 GMSSL 补丁版 Nginx:用
ssl_certificate+ssl_certificate_key加载签名链/私钥,再用ssl_certificate_enc+ssl_certificate_key_enc加载加密链/私钥 - 两套证书链文件必须为纯 PEM 格式,不能含任何注释、说明文字,也不能是 DER 或 P7B 格式


















