在 SSL/TLS 证书体系中,根证书(Root Certificate)是信任链的起点。然而,由于历史原因、平台兼容性和证书迁移等需求,根证书往往不会直接签发叶子证书,而是通过中间证书(Intermediate CA)签发。更复杂的情况是——当一个新的根证书诞生时,为了让它同时被所有平台信任,往往需要使用另一个已受信任的根证书对其进行签名,这就是交叉签名(Cross-Signature)。本文将系统讲解交叉根证书的概念、产生背景、技术原理和使用场景。
👉 如果你需要一张完整的受信任证书链支持所有主流平台,请访问 **EveryoneTrust SSL 证书购买与价格页**。
为什么需要了解交叉根证书?
在证书部署中,你可能遇到过以下问题:
- 部署了 Let's Encrypt 证书,但某些旧版 Android 设备无法访问(原因:Let's Encrypt 的 DST Root CA X3 交叉签名已于 2021 年过期)
- 服务器配置了完整证书链,但某些老版本 OpenSSL 环境依然报证书链错误
- 切换到了新 CA 的证书,但部分企业内网系统不信任(因为企业浏览器仅内置了旧的根证书)
- 根证书到期了,如何在不中断服务的情况下平滑替换?
这些问题的背后,都与交叉根证书的机制有关。理解它,才能从根本上解决证书链信任问题。
根证书信任模型基础
在深入交叉签名之前,先回顾一下根证书的信任模型。
根证书的安装位置
根证书本身是自签名的(用自己的私钥签发自己),它的可信性来自于预先安装在客户端(浏览器、操作系统)中:
| 客户端类型 | 根证书存储位置 |
|---|---|
| Windows | 受信任的根证书颁发机构(certlm.msc) |
| macOS | 钥匙串访问(Keychain Access)→ 系统根证书 |
| iOS / Android | 系统根证书区(不可见,用户不可干预) |
| Firefox | 自身内置的证书库(而非操作系统) |
| Java | JAVA_HOME/lib/security/cacerts |
| Linux 发行版 | /etc/ssl/certs/ca-certificates.crt(由系统维护) |
当浏览器验证证书链时,最后一步是检查根证书是否在本地受信任存储中:
验证路径:
example.com 证书
→ 中间 CA 证书
→ 根证书 ← 浏览器检查此证书是否在本地受信任根存储中
✅ 找到且受信任 → 验证通过
❌ 未找到 → 证书不受信任
为什么需要中间证书?
根证书通常有以下特点:
- 离线保管:根 CA 的私钥通常存放在物理安全模块(HSM)中,不连接互联网,签发操作由中间 CA 完成
- 吊销风险高:一旦根证书被吊销,所有由其签发的证书链全部失效
- 签发速度慢:中间 CA 可以高速、大量签发叶子证书
因此,实际证书链结构通常是:
example.com 证书(叶子证书 / Leaf Certificate)
└─ 由 中间 CA 证书 签发
└─ 由 根证书 签发
└─ 自签名(Root CA 的私钥签发自己的公钥)
↓
浏览器/系统的"受信任根证书存储"
什么是交叉签名?
交叉签名的定义
交叉签名(Cross-Signing) 是指:用一个新的根证书(A)为另一个已存在的根证书(B)签发证书,使得任何信任 B 的客户端也能信任 A。
简单来说:
交叉签名 = 根证书 A 对根证书 B 的"信任背书"
使得:信任 A 的客户端 ↔ 信任 B 的客户端,双方互信
什么时候需要交叉签名?
场景一:新根证书建立信任
当一个全新的 CA(比如 Let's Encrypt 的 ISRG Root X1)成立时,它的根证书不在任何客户端的受信任存储中。为了让新根证书立即获得全球客户端的信任,需要找一个已受信任的老根证书对新根证书进行交叉签名。
Let's Encrypt 的经典案例:
ISRG Root X1(新根证书,2015 年成立)
↓ 用 DST Root CA X3 交叉签名
DST Root CA X3(旧根证书,老牌 CA,1999 年成立,浏览器内置信任)
↓
新旧客户端均信任 DST Root CA X3 → 信任链通过 → ISRG Root X1 也被信任
场景二:根证书升级与迁移
当 CA 更换根证书时,为了让旧平台依然能信任新的根证书,需要通过交叉签名建立过渡:
新根证书(New Root)
↓ 交叉签名(用旧根证书签署)
旧根证书(Old Root,被所有平台信任)
↓
新平台信任 New Root,旧平台通过 Old Root → New Root 链信任
场景三:多平台兼容性
某些 CA 的根证书仅被部分平台内置信任,需要通过交叉签名来覆盖其他平台:
DigiCert Global Root G2(被大多数现代浏览器信任)
↓ 交叉签名
Baltimore CyberTrust Root(被某些企业系统和老旧平台信任)
交叉签名的技术原理
两种交叉签名类型
类型一:自签名根证书 + 交叉签名根证书
这是最常见的模式。一个根证书持有两个版本:
ISRG Root X1 自签名版本
Subject: ISRG Root X1
Issuer: ISRG Root X1(自签名)
签名算法: RSA-4096 / SHA-256
ISRG Root X1 交叉签名版本(DST Root CA X3 签发)
Subject: ISRG Root X1
Issuer: DST Root CA X3(由 DST 根证书签发)
在证书链配置中,服务器可以根据客户端的能力(SNI、协议版本)选择发送哪个版本的根证书。
类型二:中间证书的交叉签名
某些中间 CA 证书也需要交叉签名,以支持多个根证书路径:
中间证书(Intermediate CA)
→ 由 根证书 A 签发(路径 A)
→ 由 根证书 B 交叉签名(路径 B)
交叉签名证书链示例
以 Let's Encrypt 的 ISRG Root X1 为例,完整证书链如下:
现代客户端信任路径(直接信任 ISRG Root X1):
example.com 证书
→ Let's Encrypt Authority X3(中间 CA)
→ ISRG Root X1(自签名)
✅ 浏览器内置 ISRG Root X1 → 信任
旧版客户端信任路径(通过 DST Root CA X3 交叉签名):
example.com 证书
→ Let's Encrypt Authority X3(中间 CA)
→ ISRG Root X1(由 DST Root CA X3 交叉签名)
→ DST Root CA X3
✅ 浏览器内置 DST Root CA X3 → 信任
交叉签名在服务器端的配置
服务器需要同时发送两条路径的证书,客户端会根据自己信任的根证书自动选择:
Nginx 配置示例:
server {
listen 443 ssl http2;
server_name example.com;
# 叶子证书
ssl_certificate /etc/ssl/certs/example.com.crt;
# 完整证书链(包含中间证书 + 交叉签名根证书)
# 推荐顺序:叶子证书 → 中间证书 → 交叉签名根证书
ssl_certificate_chain /etc/ssl/certs/chain-with-cross-sign.crt;
ssl_protocols TLSv1.2 TLSv1.3;
}
Apache 配置示例:
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateChainFile /etc/ssl/certs/chain-with-cross-sign.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
交叉签名的典型案例:Let's Encrypt
Let's Encrypt 是理解交叉签名最好的案例。
Let's Encrypt 的根证书演变史
| 时间 | 里程碑 | 意义 |
|---|---|---|
| 2015 年 | Let's Encrypt 成立 | ISRG 根证书诞生 |
| 2015–2016 年 | 使用 IdenTrust DST Root CA X3 交叉签名 | ISRG Root X1 通过交叉签名获得全球浏览器信任 |
| 2016 年 | Let's Encrypt 正式上线 | 服务数亿证书 |
| 2018 年 | ISRG Root X1 被 Mozilla、Chrome 纳入根证书存储 | 新客户端直接信任 ISRG Root X1 |
| 2021 年 9 月 | DST Root CA X3 过期 | 旧客户端(如 Android 7 以下)若使用旧版 OpenSSL,可能无法验证新链 |
| 2021 年 9 月后 | 客户端使用 IdenTrust 直接交叉签名(绕过 DST) | 修复了 Android 7 以下的问题 |
DST Root CA X3 过期事件
2021 年 9 月 30 日,DST Root CA X3 到期(notAfter = 2021-09-30),这导致了一个广泛传播的信任问题:
DST Root CA X3 到期后的影响:
✅ 受影响的设备:
- Android 7.0 以下(使用旧版 Bouncy Castle 库)
- macOS 10.12.0 以下
- iOS 10 以下
- 某些 Linux 发行版的老版本 OpenSSL
- Java 6/7 等老版本运行环境
✅ 不受影响的设备:
- 所有主流现代浏览器(直接信任 ISRG Root X1)
- Android 7.1.1+(更新了根证书存储)
- iOS 10+
- 现代操作系统(Windows 10+、macOS 10.12+)
Let's Encrypt 随后将交叉签名切换为 IdenTrust 直接签名(ISRG Root X1 由 IdenTrust 根证书签发,而非已过期的 DST Root CA X3),解决了大部分兼容性问题。
交叉签名的常见问题
问题一:证书链不完整
症状:浏览器显示"此证书的签发者不受信任"(ERR_CERT_AUTHORITY_INVALID)
原因:服务器只发送了叶子证书和中间证书,没有包含根证书(或交叉签名根证书)
排查方法:
# 使用 SSL Labs 检测,查看 Certificate Chain 部分
# 访问 https://www.ssllabs.com/ssltest/
# 使用 openssl 检查证书链完整性
openssl s_client -connect example.com:443 -showcerts 2>/dev/null | openssl x509 -noout -subject -issuer
# 验证链是否完整(应该从叶子到根依次显示)
openssl s_client -connect example.com:443 -showcerts 2>/dev/null
解决方案:在服务器配置中添加完整的证书链文件(包含中间证书 + 交叉签名根证书)
问题二:多路径混淆
当证书链中存在两条可用信任路径时(如同时安装了 ISRG Root X1 自签名版本和交叉签名版本),某些客户端可能使用了非最优路径。
症状:SSL Labs 显示 "Chain issues: Extraneous certificates"
解决方案:确保证书链文件顺序正确,只包含必要的证书,不要包含多余的根证书
正确的证书链顺序:
1. 叶子证书(Leaf Certificate)
2. 中间证书(Intermediate CA)
3. 交叉签名根证书 / 自签名根证书(Cross-Signed or Self-Signed Root)
错误的证书链:
1. 叶子证书
2. 中间证书
3. 根证书 A
4. 根证书 B ← 多余!不要包含客户端已内置的根证书
问题三:旧平台无法信任
某些企业环境使用老版本操作系统和 TLS 库,根证书存储可能多年未更新。
解决方案:
- 为这些平台单独提供包含旧根证书的证书链
- 使用 CDN(Cloudflare、Fastly 等)作为代理,CDN 会处理跨平台兼容性问题
- 联系 CA 提供备用的证书链路径
自签名证书 vs 交叉签名 vs 完整 CA 链
| 对比维度 | 自签名证书 | 交叉签名证书 | 完整 CA 链 |
|---|---|---|---|
| 签发者 | 自己签发自己 | 由另一个根证书签发 | 由中间 CA → 根证书签发 |
| 公开信任 | ❌ 不受公开 CA 信任 | ✅ 依赖交叉签名根的信任 | ✅ 公开 CA 全平台信任 |
| 适用场景 | 内网、开发测试 | 新 CA 建立信任、平台迁移 | 生产环境 HTTPS |
| 证书链长度 | 1(自签名根) | 2(中间+根)或 3(叶子+中间+根) | 3(叶子+中间+根) |
| 维护成本 | 低(但不可用于公开场景) | 中(需管理多条路径) | 低(CA 维护) |
| 浏览器兼容性 | 仅限手动导入根证书 | 取决于交叉签名根 | 全平台兼容 |
交叉签名与证书透明(CT)
现代受信任 CA 在签发任何证书时,都必须将证书提交到 Certificate Transparency(CT)日志,交叉签名证书也不例外。
CT 日志的作用:
- 防止错误签发:CA 的任何签发行为都会公开记录,CA 无法在事后否认
- 检测恶意证书:网站管理员可以监控 CT 日志,发现是否有第三方为自己域名申请了证书
- 审计根证书:交叉签名根证书的签发行为也会被 CT 日志记录
验证命令:
# 查看证书的 SCT(签名证书时间戳)信息
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text | grep -A 5 "CT Precertificate SCT"
# 在 crt.sh 查询某域名的所有已签发证书
# https://crt.sh/?q=example.com
常见 CA 的交叉签名方案一览
| CA | 根证书 | 交叉签名方案 | 兼容性 |
|---|---|---|---|
| Let's Encrypt | ISRG Root X1 | IdenTrust 交叉签名(2021 年后) | 全平台 |
| DigiCert | DigiCert Global Root G2 | 无需交叉签名(广泛内置) | 全平台 |
| Sectigo | USERTrust RSA Root | 交叉签名到 AddTrust 旧根 | 兼容老平台 |
| GlobalSign | GlobalSign Root CA | 交叉签名到旧根证书 | 全平台 |
| SSL.com | SSL.com Root CA | 多路径交叉签名 | 全平台 |
如何检查证书链中的交叉签名
# 查看证书链中每张证书的签发者
openssl s_client -connect example.com:443 -showcerts 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
# 解读:如果 issuer 和 subject 相同,说明是自签名根证书
# 如果 issuer 和 subject 不同,说明是中间证书或交叉签名证书
# 使用 openssl verify 验证完整链
openssl storeutl -noout -text -certs /etc/ssl/certs/ca-certificates.crt 2>/dev/null
# 在线工具
# https://whatsmychain.com/ — 自动检测并修复证书链
# https://www.ssllabs.com/ssltest/ — 完整链分析
总结
交叉根证书是证书体系中连接新旧根证书、解决平台兼容性的关键机制。它的核心价值在于:
- 扩大信任范围:新根证书通过交叉签名,借道已有根证书的信任基础,快速获得全球客户端信任
- 支持平台迁移:CA 在更换根证书时,通过交叉签名实现平滑过渡,不中断现有服务
- 覆盖特殊场景:某些老旧平台的内置根证书存储无法更新,通过交叉签名可以覆盖这些场景
理解交叉签名,对于排查证书链问题、规划证书迁移、选择适合的 CA 方案都有重要帮助。
👉 部署证书时遇到链配置问题?EveryoneTrust SSL 提供一键式证书部署支持和完整的中间证书链文件,确保全平台兼容:**立即了解证书购买与技术支持**