PKI 体系回顾:CA 层次结构、证书链验证、吊销状态在 TLS 握手中的作用
好,咱们正式开始之前,先花点时间把 PKI 体系里最核心的几个概念捋一遍。你可能会觉得这些是基础,但说实话,我在做证书自动化方案的时候,发现很多问题恰恰出在这些“基础”上。尤其是吊销状态的处理,如果你不理解 CA 的层次结构和证书链是怎么工作的,那自动化方案很容易跑偏。
CA 层次结构:为什么不是单打独斗?
先问一个问题:为什么我们不直接用根 CA 给每个终端用户发证书?
理论上可以,但实际没人这么干。原因很简单——安全风险太大了。根 CA 的私钥一旦泄露,整个信任体系就崩塌了。所以业界普遍采用分层结构,也就是我们常说的 CA 层次结构。
典型的 PKI 体系分三层:
- 根 CA(Root CA):离线保存,极少使用。它的私钥通常放在硬件安全模块(HSM)里,甚至锁在保险柜里。我见过一个金融客户,根 CA 的私钥每年只开机一次,就为了签发下级 CA 的证书。
- 中间 CA(Intermediate CA):在线运行,负责签发终端证书。它受根 CA 信任,但即使它的私钥泄露,根 CA 可以吊销它的证书,整个体系还能重建。
- 终端实体证书(End-Entity Certificate):最终发给服务器、客户端或用户的证书。
这种结构的好处很明显:风险隔离。根 CA 的私钥几乎不会暴露,中间 CA 可以灵活扩展,终端证书的吊销也不会影响上层。
核心要点:CA 层次结构本质上是一种“信任传递”机制。根 CA 是信任锚点,中间 CA 是信任代理,终端证书是信任终点。
下面这张图可以帮你直观理解这个结构:
证书链验证:信任是怎么传递的?
有了层次结构,接下来就是验证环节。当客户端收到服务器证书时,它不会直接信任这个证书,而是会构建一条 证书链,一直追溯到它信任的根 CA。
验证过程大致是这样的:
- 提取证书链:服务器在 TLS 握手时会发送自己的证书,以及所有中间 CA 证书(根 CA 证书通常不发,因为客户端本地已有)。
- 自顶向下验证:从根 CA 开始,逐级验证下一级证书的签名是否有效。
- 检查有效期:每个证书的当前时间必须在有效期内。
- 检查吊销状态:每个证书是否被吊销(这一步我们后面重点讲)。
- 检查用途:证书的扩展字段(如 Key Usage、Extended Key Usage)是否允许当前的使用场景。
我记得有一次排查一个客户的问题,他们的服务器证书链里漏了一个中间 CA 证书。客户端验证到一半就断了,结果 TLS 握手失败。折腾了半天才发现是证书链不完整。所以,证书链的完整性是验证的前提,这一点在自动化方案里一定要考虑进去。
小技巧:你可以用 OpenSSL 命令手动验证证书链:
openssl verify -CAfile root-ca.pem -untrusted intermediate.pem server.pem
如果输出是 server.pem: OK,说明链是完整的。
吊销状态在 TLS 握手中的作用
好,重点来了。证书链验证里有一个环节经常被忽略——吊销状态检查。为什么它重要?
你想想看,一个证书即使还在有效期内,如果私钥泄露了,或者证书被误发了,那它就应该被吊销。如果 TLS 握手时不检查吊销状态,那这个证书就相当于“带病上岗”,安全形同虚设。
在 TLS 握手中,吊销状态检查通常发生在客户端验证服务器证书链的时候。具体来说:
- 客户端收到服务器证书链后,会逐个检查每个证书的吊销状态。
- 检查方式有两种主流方案:CRL(证书吊销列表)和 OCSP(在线证书状态协议)。
- 结果处理:如果某个证书被吊销,客户端必须拒绝连接。
我曾经遇到过一个案例:某电商平台的服务器证书被吊销了,但因为客户端没有做吊销检查,用户依然能正常访问。结果中间人攻击者利用这个漏洞伪造了服务器身份,窃取了大量用户数据。嗯,从那以后,我对吊销检查的自动化方案格外上心。
注意:吊销状态检查不是可选项,而是安全基线。尤其是在金融、政务等高安全场景下,跳过吊销检查等于把大门敞开。
下面这个表格可以帮你快速对比 CRL 和 OCSP 的差异:
| 特性 | CRL(证书吊销列表) | OCSP(在线证书状态协议) |
|---|---|---|
| 工作原理 | CA 定期发布一个包含所有吊销证书序列号的列表 | 客户端实时向 OCSP 响应器查询单个证书的状态 |
| 实时性 | 较低,取决于 CRL 的更新频率(通常几小时到几天) | 较高,可以做到秒级响应 |
| 网络开销 | 客户端需要下载整个 CRL 文件(可能很大) | 每次查询只传输少量数据 |
| 隐私性 | 较好,客户端不需要暴露自己访问的证书 | 较差,OCSP 响应器能知道客户端正在访问哪个证书 |
| 适用场景 | 离线环境、内网环境、对实时性要求不高的场景 | 互联网环境、高实时性要求的场景 |
在实际的 TLS 握手中,吊销状态检查的流程大致如下:
- 客户端收到服务器证书链。
- 客户端检查证书链中每个证书的 CRL 分发点(CDP)或 OCSP 响应器地址(Authority Information Access 扩展)。
- 客户端发起 CRL 下载或 OCSP 查询。
- 根据返回结果判断证书状态:Good(正常)、Revoked(已吊销)或 Unknown(未知)。
- 如果状态是 Revoked,客户端立即终止 TLS 握手。
这里有一个容易被忽略的点:OCSP 响应器的可用性。如果 OCSP 响应器挂了,客户端该怎么办?是放行还是拒绝?
我个人习惯的做法是:软失败(Soft-fail)——如果 OCSP 响应器不可用,客户端可以暂时信任证书,但会记录日志并触发告警。但如果你在金融或政务场景,建议用硬失败(Hard-fail)——响应器不可用就直接拒绝连接。这两种策略没有绝对的对错,取决于你的安全等级要求。
总结一下:吊销状态检查是 TLS 握手中的“守门员”。没有它,证书链验证就是不完整的。而自动化方案的核心目标,就是让这个“守门员”更高效、更可靠。