交叉签名证书(Cross Signed Certificate)是 SSL/TLS 基础设施中一个重要但常被误解的概念。本文深入解释交叉签名的原理、适用场景以及 OpenSSL 操作方法。
什么是交叉签名?#
交叉签名是指由一个 CA(证书颁发机构)对另一个 CA 的证书进行签名。签名的对象是 CA 证书本身,而不是终端实体证书。
1
2
3
4
|
原始链:Root CA → Intermediate CA → Server Certificate
交叉签名链:Root CA (新) → Cross-signed Intermediate CA → Server Certificate
↑
由新Root CA签名
|
关键特征:
- 交叉签名证书的 Subject(主题)与原始中间 CA 相同
- Issuer(颁发者)变为进行交叉签名的根 CA
- 公钥与原始中间 CA 完全相同
典型使用场景#
1. 多根 CA 信任#
企业可能有两个不同的根 CA(如并购后的整合),需要让一张证书同时被两个根 CA 信任。
1
|
场景:公司有两个根 CA(Root CA 1 和 Root CA 2),都需要信任同一张服务器证书
|
2. 旧客户端兼容性#
某些老旧客户端只信任特定的根 CA,通过交叉签名让新证书也能被这些客户端接受。
3. 证书迁移#
在 CA 机构迁移过程中,保持双签名确保平滑过渡。
实战:创建与验证交叉签名证书#
步骤 1:创建两个根 CA#
1
2
3
4
5
6
7
8
9
|
# 根 CA 1
openssl genrsa -out /tmp/root-ca1.key 2048
openssl req -x509 -new -nodes -key /tmp/root-ca1.key -days 3650 \
-subj "/C=CN/O=Company/CN=Root CA 1" -out /tmp/root-ca1.crt
# 根 CA 2
openssl genrsa -out /tmp/root-ca2.key 2048
openssl req -x509 -new -nodes -key /tmp/root-ca2.key -days 3650 \
-subj "/C=CN/O=Company/CN=Root CA 2" -out /tmp/root-ca2.crt
|
步骤 2:创建并签名中间 CA#
1
2
3
4
5
6
7
8
9
10
11
12
|
# 创建中间 CA 密钥和 CSR
openssl genrsa -out /tmp/intermediate.key 2048
openssl req -new -key /tmp/intermediate.key \
-subj "/C=CN/O=Company/CN=Intermediate CA" \
-out /tmp/intermediate.csr
# 由根 CA 1 签名中间 CA
openssl x509 -req -in /tmp/intermediate.csr \
-CA /tmp/root-ca1.crt -CAkey /tmp/root-ca1.key \
-days 1825 -sha256 \
-extfile <(echo "basicConstraints=critical,CA:TRUE") \
-out /tmp/intermediate.crt
|
步骤 3:创建交叉签名证书#
关键步骤:使用根 CA 2 对同一个 CSR 进行签名,生成交叉签名版本。
1
2
3
4
5
|
openssl x509 -req -in /tmp/intermediate.csr \
-CA /tmp/root-ca2.crt -CAkey /tmp/root-ca2.key \
-days 1825 -sha256 \
-extfile <(echo "basicConstraints=critical,CA:TRUE") \
-out /tmp/intermediate-cross.crt
|
⚠️ 注意:必须使用与原始 CSR 相同的文件,否则公钥不匹配会导致验证失败。
验证交叉签名证书:
1
|
openssl x509 -in /tmp/intermediate-cross.crt -noout -subject -issuer
|
输出示例:
1
2
|
subject=O = Company, CN = Intermediate CA
issuer=O = Company, CN = Root CA 2
|
步骤 4:创建服务器证书#
1
2
3
4
5
6
7
8
9
|
# 创建服务器密钥和 CSR
openssl genrsa -out /tmp/server.key 2048
openssl req -new -key /tmp/server.key \
-subj "/CN=www.example.com" -out /tmp/server.csr
# 由原始中间 CA 签发服务器证书
openssl x509 -req -in /tmp/server.csr \
-CA /tmp/intermediate.crt -CAkey /tmp/intermediate.key \
-days 365 -sha256 -out /tmp/server.crt
|
步骤 5:使用交叉签名证书链验证#
方式一:通过根 CA 1 验证(原始链)
1
2
3
|
openssl verify -CAfile /tmp/root-ca1.crt \
-untrusted /tmp/intermediate.crt \
/tmp/server.crt
|
方式二:通过根 CA 2 验证(交叉签名链)
1
2
3
|
openssl verify -CAfile /tmp/root-ca2.crt \
-untrusted /tmp/intermediate-cross.crt \
/tmp/server.crt
|
两种方式都应该输出:
证书链可视化#
1
2
3
4
5
6
7
8
9
|
原始证书链(通过 Root CA 1):
Root CA 1
└─ Intermediate CA (由 Root CA 1 签发)
└─ Server Certificate
交叉签名证书链(通过 Root CA 2):
Root CA 2
└─ Intermediate CA - Cross Signed (由 Root CA 2 签发,相同公钥)
└─ Server Certificate
|
常见错误与排查#
错误:unable to get local issuer certificate#
原因:中间 CA 证书链不完整
解决:确保提供正确的中间 CA 证书(交叉签名版本)
错误:invalid CA certificate#
原因:中间 CA 缺少 CA 扩展(basicConstraints=CA:TRUE)
解决:签名时添加 -extfile <(echo "basicConstraints=critical,CA:TRUE")
错误:certificate chain too long#
原因:中间 CA 的 pathlen 限制
解决:确保 pathlen 足够或设置为 0
最佳实践#
- 保持密钥一致:交叉签名必须使用与原始证书完全相同的公钥
- 设置正确的 CA 扩展:中间 CA 必须包含
basicConstraints=CA:TRUE
- 有效期管理:交叉签名证书的有效期不应超过原始证书
- 验证双重链:部署后同时验证两个根 CA 的信任链
- 文档记录:记录哪些证书使用了交叉签名及原因
查看证书详细信息#
1
2
3
4
5
6
|
# 查看证书扩展
openssl x509 -in intermediate-cross.crt -noout -text | grep -A3 "X509v3"
# 比较两个版本的中间 CA(公钥应该相同)
openssl x509 -in intermediate.crt -noout -modulus
openssl x509 -in intermediate-cross.crt -noout -modulus
|
交叉签名是实现多 CA 信任和证书平滑迁移的重要技术。核心要点:
- 交叉签名证书与原始证书共享相同的公钥
- 不同的 Issuer 允许在不同的信任域中使用
- OpenSSL 通过
-untrusted 参数指定中间 CA 证书链
理解并正确使用交叉签名,可以解决企业多 CA 环境下的证书信任问题。
参考来源: