3. 创建中间 CA 证书并签发
中间 CA 的定位与 pathlen 约束
中间 CA 位于根 CA 与终端实体证书之间,它由根 CA 签发,自身也是 CA 证书(CA:TRUE),但必须通过 basicConstraints 中的 pathlen 限制其下游还能再挂几层 CA。本例目标:用根 CA 签发一个中间 CA 证书,设置 pathlen:0,使其只能签发终端证书、不能再签发下级 CA,并验证链的层级关系。
准备中间 CA 的私钥与 CSR
中间 CA 的私钥建议同样加密保存,避免明文落盘。先生成受密码保护的私钥,再生成 CSR。CSR 中只放主题信息,CA 相关扩展由根 CA 在签发时通过扩展文件注入。
# 1. 生成中间 CA 加密私钥(AES-256)
openssl genrsa -aes256 -out intermediateCA.key 4096
# 2. 生成中间 CA 的 CSR
openssl req -new -key intermediateCA.key -out intermediateCA.csr \
-subj "/C=CN/O=Example Org/OU=PKI/CN=Example Intermediate CA"
用根 CA 签发中间 CA 证书
关键在扩展文件:basicConstraints=critical,CA:TRUE,pathlen:0 表示该证书是 CA 证书,且其下游只能签发终端证书;keyUsage 必须包含 keyCertSign 和 cRLSign,否则无法作为签发者使用。
# intermediate_ext.cnf
[ v3_intermediate_ca ]
basicConstraints = critical, CA:TRUE, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer
# 用根 CA 签发中间 CA 证书,有效期 1825 天
openssl x509 -req -in intermediateCA.csr \
-CA rootCA.crt -CAkey rootCA.key -CAcreateserial \
-out intermediateCA.crt -days 1825 -sha256 \
-extfile intermediate_ext.cnf -extensions v3_intermediate_ca
验证证书链的层级关系
先确认中间 CA 证书自身的扩展是否正确,再用 openssl verify 验证链。注意:验证终端证书时,中间 CA 属于“非受信中间证书”,需通过 -untrusted 传入,根 CA 通过 -CAfile 作为信任锚。
# 查看中间 CA 证书的扩展
openssl x509 -in intermediateCA.crt -noout -text | grep -A3 "Basic Constraints"
# 期望输出:CA:TRUE, pathlen:0
# 验证中间 CA 证书本身(由根 CA 签发)
openssl verify -CAfile rootCA.crt intermediateCA.crt
# 期望输出:intermediateCA.crt: OK
# 验证终端证书链(示例:server.crt 由中间 CA 签发)
openssl verify -CAfile rootCA.crt -untrusted intermediateCA.crt server.crt
# 期望输出:server.crt: OK
若
openssl verify 报 unable to get local issuer certificate,通常是 -untrusted 未传入中间 CA 证书,或中间 CA 证书缺少 keyCertSign。若报 path length constraint exceeded,说明链中 CA 层数超过了 pathlen 限制。中间 CA 私钥一旦泄露,攻击者可签发任意终端证书。生产环境中应将中间 CA 私钥存放在受控的签发服务器或 HSM 中,并限制其访问权限;根 CA 私钥应离线保存,仅用于签发中间 CA。
快速复查清单
| 检查项 | 命令/位置 | 通过条件 |
|---|---|---|
| 中间 CA 私钥加密 | intermediateCA.key | 文件头含 ENCRYPTED |
| CA 基本约束 | openssl x509 -text | CA:TRUE, pathlen:0 |
| 密钥用法 | openssl x509 -text | 含 keyCertSign、cRLSign |
| 签发者匹配 | issuer vs subject | 中间 CA 的 issuer = 根 CA 的 subject |
| 链验证 | openssl verify | 输出 OK |