1. OCSP 协议基础:工作原理、消息结构、CRL 对比

各位同学,欢迎来到第一讲。咱们开门见山,先聊一个最根本的问题:为什么需要 OCSP?

你想想看,数字证书用得好好的,突然有一天私钥泄露了,或者证书绑定信息变了。这时候如果系统还继续信任这张证书,后果可想而知。CRL(证书吊销列表)是最早的解决方案,但我在很多项目里遇到过它的性能瓶颈。说白了,CRL 就像一张通缉令名单,客户端得定期下载整个名单,自己比对。CA 机构越大,名单越厚,下载越慢。

OCSP(在线证书状态协议)就是冲着这个问题来的。它把「查名单」变成了「问服务器」。客户端只问一张证书的状态,服务器只回答一张证书的状态。这听起来简单,但背后的设计细节值得好好扒一扒。

1.1 OCSP 的核心思想

OCSP 由 RFC 6960 定义。它的基本逻辑很直白:请求-响应。客户端拿着证书的序列号等信息,向 OCSP 响应器发一个请求,响应器查完状态后返回一个签名的响应。这里要注意,响应是带数字签名的,所以客户端可以验证这个响应是否来自可信的响应器。

我刚开始接触 OCSP 时有个误区:以为 OCSP 响应器就是 CA 自己。后来踩过坑才知道,CA 可以委托独立的 OCSP 响应器来处理,甚至可以通过预签名来实现离线响应,这在后面讲性能优化时会重点展开。

整个交互流程其实很清晰,我画了一张图帮你理解:

OCSP 核心交互流程 OCSP 核心交互流程图 客户端 OCSP 响应器 CA / 证书数据库 ① OCSP 请求 ② OCSP 响应 ③ 查询证书状态 关键点 • 请求最小化 • 响应必须签名 • 响应有生存期 • 支持委托响应器 • 可离线预签名
小提示:上面这张图里的虚线部分——OCSP 响应器查询 CA 数据库——在实际部署中是个关键性能瓶颈。很多优化手段都围绕着怎么「跳过」这一步,比如缓存、预签名、或者使用只读副本。后面章节我会专门讲这个。

1.2 消息结构:拆开看看里面长什么样

OCSP 的请求和响应都是用 ASN.1 编码的。嗯,ASN.1 可能听起来有点吓人,但别担心,我们只看核心字段。

请求消息

一个 OCSP 请求包含什么呢?核心就是待查询的证书标识。这个标识由三部分组成:

  • hashAlgorithm:对证书签发者 DN 和公钥做哈希的算法,通常是 SHA-1(虽然老,但这里还在用)。
  • issuerNameHash:签发者 DN 的哈希值。
  • issuerKeyHash:签发者公钥的哈希值。
  • serialNumber:证书的序列号。

这里有个坑。我记得有一次排查问题,发现客户端总是报「证书状态未知」。查了大半天,最后发现是 issuerNameHash 的计算方式不对——有的实现用了完整 DER 编码,有的只用了字符串,结果对不上。所以在写代码对接时,一定要看清楚 RFC 里关于哈希输入数据的具体要求。

响应消息

OCSP 响应是签名的,结构上分为两部分:BasicOCSPResponse 和 签名。BasicOCSPResponse 里最重要的字段是:

  • certStatus:三种值——good、revoked、unknown。
  • thisUpdate:这个响应的生成时间。
  • nextUpdate:下个更新时间的建议值,缓存策略的核心依据。
  • producedAt:签名时间(通常和 thisUpdate 一致)。
经验之谈:很多性能监控系统都会盯着 nextUpdate 和实际到达时间的差值。如果客户端在 nextUpdate 之后还使用旧响应,就有安全风险;但如果客户端每次请求都等新响应,性能就会下降。这个平衡点,就是我们后面做性能分析的关键指标。

1.3 对比 CRL:为什么速度差这么多?

搞 OCS P 的人,一半以上的优化思路都是从「怎么比 CRL 快」出发的。咱们直接看对比表:

对比项 CRL(证书吊销列表) OCSP(在线证书状态协议)
数据量 整个 CA 的所有吊销证书,可能几 MB 甚至几十 MB 单个证书状态,通常 1KB 以内
更新方式 定期下载完整列表(如每 24 小时) 实时查询,支持缓存
签名验证 一次签名验证,验证整个列表 每次响应单独签名验证
网络开销 高(大文件传输) 低(小请求/响应)
冷启动问题 首次下载慢 首次查询可能慢,但可预签名优化
实时性 差(更新周期内可能有吊销证书仍显示有效) 好(查询结果基于最新状态)
客户端复杂度 需要解析 ASN.1 列表、做二分查找 需要解析 ASN.1 响应、验证签名
避坑指南: 我曾经在某个高并发场景下看到团队直接用 CRL,结果每个客户端每 6 小时就去拉一次 30MB 的 CRL 文件,CDN 回源带宽直接被打满。后来改成 OCSP 加预签名缓存,带宽降了 95%。所以如果你手里的系统是面向互联网用户的,千万别图省事用 CRL 做实时验证。

1.4 CRL 和 OCSP 的混合使用场景

你可能觉得「OCSP 全面优于 CRL」,那就直接全用 OCSP 不就行了?现实没那么简单。

CRL 的优点在于它是一次签名,验证成本均摊到所有证书上。如果客户端有缓存空间,CRL 的验证成本其实很低。OCSP 则每次都要单独验证签名,如果请求量上来,响应器端的签名计算压力会非常大。

我见过的最佳实践是分层使用:内部网络用 CRL 做批量验证,外部用户用 OCSP 做实时查询。或者像一些浏览器那样,先查 OCSP,如果响应器没响应,再退回到 CRL。这种降级策略在工程上很实用。

1.5 本章要点总结

  • OCSP 的本质:用一问一答替代 CRL 的下载全量列表,核心目标是减少网络和计算开销。
  • 消息结构:请求靠证书标识定位,响应靠签名保证可信,nextUpdate 是性能缓存的关键参数。
  • CRL 对比:CRL 适合批量、可缓存、对实时性要求不高的场景;OCSP 适合实时、高并发、带宽敏感的场景。没有的好坏,只有适合不适合。
  • 混合策略:生产环境里常见 OCSP + CRL 降级,或者 OCSP + 短周期缓存。