OCSP详解:请求/响应结构、OCSP Responder 与在线查询过程
说实话,CRL 那套下载列表查状态的方式,虽然实现简单,但用起来总有点“笨重”。你想想看,每次都得拉一整个文件下来,哪怕你只关心一张证书。所以就有了 OCSP(在线证书状态协议),说白了就是“按需查询”。
我个人非常喜欢 OCSP 的设计思路——它把查状态这件事,从“批量下载”变成了“单次问询”。客户端发个请求,服务端回答“好/坏/未知”,干净利落。那它具体是怎么工作的?我们从最底层的报文结构开始聊。
OCSP 请求结构
OCSP 请求的核心目标就是一个:告诉服务端“帮我查查这张证书现在啥状态”。它不需要你发整张证书过去,只需要几个关键标识就够了。
一个典型的 OCSP 请求,主要包含两部分:
- 协议版本:目前基本都是 v1(RFC 6960)。
- CertID:这是核心,用来唯一标识被查询的证书。它由三部分构成:
- 签发者公钥的 Hash(通过证书的
issuerPublicKey计算 SHA-1 或 SHA-256)。 - 签发者名称的 Hash(证书的
issuerDN)。 - 被查询证书的序列号。这个最直接,因为序列号在同一个 CA 域内是唯一的。
- 签发者公钥的 Hash(通过证书的
我的一点经验:有人会问,为什么不直接发证书序列号?非得加上签发者Hash?这是为了防止不同CA之间出现序列号冲突。我见过一个案例,两个不同CA误签了相同序列号的证书,如果不加签发者标识,OCSP响应器就查错了。
另外,OCSP 请求里还可以带上一个可选的 Nonce(随机数),用来防止重放攻击。这个后面我们会聊到。
OCSP 响应结构
服务端收到请求后,会返回一个响应。响应的核心就是那张证书的状态。状态只有三种:
| 状态值 | 含义 | 说明 |
|---|---|---|
good |
证书有效 | 未吊销,且在有效期内 |
revoked |
证书已吊销 | 会附带吊销时间和原因 |
unknown |
未知状态 | 找不到该证书信息 |
除了状态本身,响应里还有几个关键字段:
- thisUpdate:这份响应的生成时间。
- nextUpdate:建议下一次查询的时间。客户端可以在此之前缓存这个结果,不用重复查。
- 签名:整个响应必须由 CA 或受信任的 OCSP 响应器签名。客户端需要验证这个签名,否则任何人都可以伪造一个“good”响应来骗你。
坑! 我曾经遇到过一个问题:一个客户端的 OCSP 缓存时间写死了 24 小时,但 CA 的响应里
nextUpdate 设置的只有 4 小时。结果这 24 小时里,证书被吊销了,客户端还傻乎乎地认为它有效。记住,nextUpdate 是建议,但客户端应该以更短的那个为准。
OCSP Responder 的角色
OCSP Responder 就是那个回答你“在不在”的服务端。它可以是 CA 自己部署的,也可以是第三方运营的。
Responder 的核心任务就一件事:查数据库或缓存,然后返回签名结果。但它面临一个很现实的问题——性能。
你想想看,一个大的 CA 可能每天要处理几百万次 OCSP 查询。每次查询都去硬盘里翻数据库,响应时间肯定撑不住。所以 OCSP Responder 在架构上通常这么玩:
- 内存缓存:将最近生成的响应缓存起来。因为同一张证书可能被反复查询,缓存命中率很高。
- 预签名:对有效期内的证书提前生成签名好的响应。查询时直接返回预签名结果,不需要实时签名,性能会好很多。
- 负载均衡:通过多个节点分摊查询压力。
避坑指南:预签名虽然快,但有个隐患——万一证书在这段时间内被吊销了怎么办?所以预签名的时间窗口不能太长,我一般建议在 5-10 分钟。同时,证书吊销时,必须能够立即刷新预签名缓存。
在线查询过程总结
我把整个 OCSP 在线查询的过程归纳成下面这张图,你一看就明白了。
我来把这张图的逻辑走一遍:
- 客户端构造请求:从证书中提取签发者Hash和序列号,拼接成一个CertID。如果需要防重放,再加一个Nonce。
- 发送给OCSP响应器:通过HTTP POST或GET方式把请求发过去(常见的是POST,因为请求体可以大一些)。
- 响应器处理:先查自己的缓存或数据库,找到这张证书对应的状态。同时验证请求格式和Nonce是否匹配。
- 返回签名响应:根据状态返回good/revoked/unknown,并签名整个响应。
- 客户端验证:收到响应后,第一件事就是验签名。如果签名不对,直接拒绝。然后检查Nonce是否一致,防止重放。最后看一眼
thisUpdate和nextUpdate,决定要不要缓存这个结果。
我个人觉得,OCSP 最巧妙的地方就在于它把“查状态”这件事拆成了“问”和“答”两个动作,而且每个动作都考虑到了安全性和性能。不过,它也不是万能的,最大的问题就是——如果客户端连不上OCSP响应器怎么办?这种“软失败”策略很容易被攻击者利用。这也是为什么后来有了OCSP Stapling(证书状态钉扎),把“问”这个动作交给了服务端,而不是客户端。