摘要

  • RFC 9919 要求轻量 OCSP 答复必须包含 nextUpdate;缺失即拒绝,客户端当前时间越过它也必须按陈旧答复拒绝。
  • 数字签名证明获授权答复者对 OCSP 内容的认证与完整性,不会给旧的 good 状态续期,也不保护外围 HTTP 缓存头。
  • 可复核的控制记录必须包含证书、答复者、签名时间窗、客户端时间与容差、缓存路径、验证策略和应用最终动作。

缓存命中了,控制仍可能失败

把一份 OCSP 答复放进缓存后,它会出现两种完全不同的寿命。第一种是密码学寿命:只要算法和密钥条件允许,签名可以长期验证成功。第二种是状态寿命:答复者只承诺某个证书状态在一个明确的时间窗内具有决策意义。前者尚未结束,不代表后者仍在继续。

RFC 9919 面向证书量和查询量都很大的 PKI。它允许预先制作答复、压缩消息、在客户端与网络中缓存,并把答复“装订”到 TLS 等协议交换里。这样可以削减带宽、往返和集中式答复者的峰值负荷。

真正支撑这种扩展性的不是对中间节点的信任,而是客户端可本地执行的窄规则。thisUpdate 表示答复者最近一次确认该状态正确的时间,producedAt 表示签署答复的时间,nextUpdate 表示更新信息最迟何时可得。RFC 9919 把 nextUpdate 设为必需字段。没有它,客户端必须拒绝;当前时间晚于它,客户端必须把答复视为陈旧。

因此,一份旧答复无需遭到篡改就会失去权威。此后可能已经出现新的 revoked 状态,而旧对象仍然带着数学上完好的签名。签名回答“谁对哪些字节负责”,时间窗回答“这些字节中的状态主张还能否用于现在的决定”。

good 不是证书全身检查

RFC 6960 对 good、revoked 和 unknown 的含义有意保持克制。good 至少表示:答复者没有把所询问序列号、且处在证书有效期内的证书记为已撤销。它不必证明证书从未伪造或确实签发,也不替代证书有效期、路径构建、服务名称、用户身份或业务授权检查。

客户端在接受签名答复前,还要确认答复中的证书标识与请求对象对应,签名有效,签名者对相关 CA 具有 OCSP 答复权限,thisUpdate 足够近,nextUpdate 仍在未来。应用层随后才把这一结果与其他验证条件结合。

“OCSP 通过”把这些判定压成一个绿灯。它无法说明 HTTP 是否只返回了错误,答复者是否有权,时间是否有效,证书是否完成其他验证,应用最终是否建立连接。事故分析若只留下这个标签,就失去了定位控制失败的能力。

时钟不是背景服务,而是验证输入

逐请求 nonce 能提供请求与答复的一一对应,但会妨碍预生成和共享缓存。RFC 9919 因而建议客户端通常不要加入请求扩展。如果客户端发送 nonce 而答复中没有,除非它已知答复者支持 nonce,一般不应只因缺失就拒绝,而应回到基于时间的新鲜度判断。

这要求客户端与答复者都拥有准确时间。客户端必须判断当前时间落在 thisUpdate 与 nextUpdate 之间。为处理轻微时钟差,可以配置小幅容差,但数值应由环境真实的同步精度决定,而不是成为所有系统共用的宽限期。

时钟偏快会把尚新鲜的答复提前拒绝,造成可用性故障;时钟偏慢则可能在撤销发生后继续接受过期 good。所以“时间服务进程在线”不是充分证据。验证记录还应保留实际使用的时间、来源、偏差或不确定度、容差以及附近是否发生跳变。

同一份 HTTP 消息里有两套新鲜度

RFC 9919 要求较小的 OCSP 请求使用 GET,以便共享缓存。答复可携带 Date、Last-Modified、Expires、ETag 与 Cache-Control。max-age 可以让客户端在 nextUpdate 前分散刷新,避免热门证书在同一时刻制造查询尖峰;must-revalidate 约束缓存故意返回陈旧内容。

这些字段解决的是传输层问题:中间缓存能否不访问源站而复用表示。签名 OCSP 时间窗解决的是状态权威问题:这份认证过的证书状态主张是否仍能参与接受决定。RFC 9919 明确指出,HTTP 头没有密码学保护,只能指导缓存;最终必须依赖 OCSP 答复内部签名覆盖的值。

所以,HTTP 的 Expires 不能把 nextUpdate 向后推。缓存认为对象“新鲜”,也不能免除客户端检查签名时间窗。若代理持续返回过期对象,客户端可尝试绕过缓存重新获取;新取得的答复仍须经过同样的签名、权限、标识与时效检查。

TLS 装订也只改变保管与交付路径。TLS 服务器代为携带 OCSP 答复,减少额外连接,并没有因此成为证书状态的作者。客户端的本地验证边界保持不变。

SHA-256 迁移只修复其中一层

RFC 9919 取代 2007 年的 RFC 5019,要求符合新规范的客户端在 CertID 的颁发者名称和公钥哈希中使用 SHA-256。继续为旧生态保留 SHA-1 会增加实现复杂度和攻击面,因此迁移有必要。

但现代哈希不会自动产生当前状态。使用 SHA-256 标识的答复仍可能过期;使用强签名的答复仍可能来自无权答复该 CA 的签名者;完全合规的缓存仍可能把数据交给时钟错误的客户端。算法升级应单独验证,不能成为整条证书接受链的替代证据。

记录一项可重放的决定

控制收据应保留目标证书指纹与序列号、颁发者名称和密钥哈希及算法、完整 OCSP 字节与哈希、答复者标识、签名者链与授权结果、producedAt、thisUpdate、nextUpdate、状态和撤销字段。

本地上下文同样重要:接收时间、所用时钟及其不确定度、容差、nonce 行为、验证器版本与策略、接受或拒绝原因,以及应用随后执行的动作。HTTP 缓存节点、Age、ETag、Expires、绕缓存重试等可作为交付证据保存,但必须明确它们不属于签名状态主张。

四个现实层由此分开:HTTP 交易证明字节怎样到达;签名 OCSP 证明获授权答复者在限定时间内说了什么;本地日志证明客户端为何作出决定;应用记录证明决定产生了什么后果。任何一个“成功率”都不能代替其余三层。

来源