第三讲:证书链概念——根证书、中间证书、叶子证书、证书路径构建
大家好啊,咱们接着来。
上一讲我们把 X.509 证书的格式撸了一遍,你大概知道证书里面装了公钥、签名、有效期这些玩意儿。但有个问题我一直想强调:光有一张证书,你没法判断它是不是靠谱的。就像你拿到一张身份证,得看发证机关是谁,发证机关又得看上级机关,最后追到公安部——证书链就是这么个信任链条。
3.1 证书链的层级模型
我个人习惯把证书链想象成一棵倒过来的树。最上面是根,中间是分叉,最下面是叶子。三类证书各司其职:
- 根证书(Root CA):自签名,信任的起点。浏览器和操作系统里预装的那些就是。
- 中间证书(Intermediate CA):由根签发,用来签发叶子证书。根不出面,中间当“二传手”。
- 叶子证书(End Entity / Leaf):最后给网站、用户、设备用的,也就是你 HTTPS 天天见到的那张。
下面这张图把关系画清楚了:
3.2 根证书:信任的起点
根证书是所有信任的源头。它自己签发自己,我们管这叫自签名证书。浏览器也好,操作系统也好,里面都预装了一堆根证书——这些就是它“信任”的基础。
我记得刚入行时有个误区:以为根证书越多越安全。其实恰恰相反。如果某个根证书的私钥泄露了,攻击者可以用它签发任意中间证书,然后伪造任何网站的叶子证书。——这就是 CA 信任模型最大的风险。所以现在严格限制根证书的私钥存储,HSM(硬件安全模块)是标配。
3.3 中间证书:安全缓冲层
那为什么要有中间证书?说白了就是为了把根藏起来。根证书的私钥可以锁在保险柜里只断网使用,日常干活用中间证书。就算中间证书出事了,吊销它就行,根不受影响。
中间证书可以有一级,也可以有多级。我见过最长的一条链有 4 级中间证书。但通常 2~3 级就够了。级数越多,验证开销越大——每多一级就要多检查一次签名。
| 层级 | 用途 | 数据示例 |
|---|---|---|
| 中级 CA 1 | 用于签发网站证书 | Let's Encrypt Authority X3 |
| 中级 CA 2 | 用于签发企业内部证书 | 内部 Root 签发后交给部门子 CA |
| 交叉证书 | 桥接不同信任域 | 两个根不用互相嵌入,靠交叉中间证书 |
3.4 叶子证书:最终的业务凭证
叶子证书就是最终用户看到的那个。HTTPS 网站用的、代码签名用的、邮件加密用的,都是叶子证书。它有一个基本约束:不能再签发下级证书(CA 标志位为 False)。
你想想看,如果叶子证书能发下级证书,那任何一台服务器被攻破就能签发它自己的假证书,那信任体系就彻底崩塌了。
我建议大家巡检时重点看叶子证书的这几项:
- Subject 与 SAN:是否与你访问的域名匹配?
- 有效期:是否在有效期内?提前 30 天该预警替换。
- 签名算法:是否还在用 SHA-1?赶紧换 SHA-256 以上。
- 吊销状态:通过 OCSP 或 CRL 检查是否已被吊销。
3.5 证书路径构建
证书路径构建(Certificate Path Building)是整个验证环节的第一步。客户端拿到一张叶子证书后,需要自己拼出从叶子到根的完整链条。这个过程不是简单地把证书列表拼起来就完事。
我曾在项目中踩过一个大坑:某个内部系统用了自建 CA,根证书和中间证书都正确,但客户端总是报“证书链不完整”。查了半天,原来是因为服务器没有把中间证书发送给客户端。OpenSSL 默认只发叶子证书,中间证书需要手动拼接。解决方案是把中间证书和叶子证书放到一个 PEM 文件里一起发送。
路径构建的典型步骤:
- 收集候选证书:从服务器发来的证书列表、本地信任存储、授权信息访问(AIA)扩展指向的 URL。
- 匹配签发者:当前证书的签发者(Issuer)等于下一张证书的主体(Subject)。
- 检查签名:用下一张证书的公钥验证当前证书的数字签名。
- 验证约束:检查路径长度约束、名称约束、策略约束等。
- 信任锚匹配:最后一张证书必须与本地信任的根证书完全一致。
# OpenSSL 验证证书链的常用命令
# 假设你有 server.pem、intermediate.pem、root.pem 按顺序拼接
cat server.pem intermediate.pem root.pem > chain.pem
openssl verify -CAfile root.pem -untrusted intermediate.pem server.pem
# 或者直接用 -CApath 指定根目录
openssl verify -CApath /etc/ssl/certs/ server.pem
3.6 常见证书链问题速查
| 问题现象 | 常见原因 | 快速排查 |
|---|---|---|
| 浏览器提示不安全,但有锁 | 中间证书缺失或顺序错误 | SSL Labs 测试或 OpenSSL s_client -showcerts |
| 签名验证失败 | 证书与私钥不匹配 | openssl x509 -noout -modulus vs openssl rsa -noout -modulus |
| 证书链不完整 | 服务器未发送中间证书 | 检查 AIA 扩展或手动拼接 |
| 根证书不信任 | 根未导入系统信任存储 | 检查 /etc/pki/tls/certs/ 或 Windows 受信任根颁发机构 |
| 路径长度超限 | 中间证书的 pathLenConstraint 限制 | 查看中间证书 Basic Constraints 扩展 |
嗯,到这里证书链的概念就基本讲完了。根证书是信任锚,中间证书隔离风险,叶子证书干实事,路径构建就是把它们串起来。下一轮我们会动手解析实际证书链,看看里面每个字段是怎么对应起来的。今天先消化这些基础,有任何疑问欢迎留言讨论。