探究 OCSP（在线证书状态协议）

前言#

在 SSL/TLS 证书领域，我们不得不提到 OCSP（在线证书状态协议）。它是用于在线检查证书状态的一种协议，用于客户端判断目标服务器是否可信。最近与 Steamfinder 的讨论中，他提到卡巴斯基企业版报告某个网站的 SSL/TLS 证书状态错误，而标准版则没有报告。当时我猜测可能是该网站的 OCSP 配置出了问题（可能是需要开启 OCSP Stapling，但是该网站未配置），企业版更注重安全所以检查 OCSP Stapling，而标准版不检查。

验证#

首先要说明的是，OCSP 的设计目标是为了更好地检查证书吊销状态，因此在设计上考虑了轻量化等因素。相比之前的证书吊销列表（CRL）方式，需要从证书授权机构（CA）下载一个庞大的文件，并匹配目标证书是否在吊销列表中，非常繁琐且响应速度缓慢。而且，证书的状态需要等待 CA 更新 CRL，这存在一定的时间差。如果在时间差内访问一个被吊销的网站，但是 CRL 尚未更新，那么对于普通用户而言，安全级别就会降低，因为这个被吊销的证书在时间差内被验证为可信！OCSP 的出现正是为了进行轻量级的实时在线验证。

在这之前，我已经验证了 Chrome 和 Firefox 是否会主动发起 OCSP 请求。通过我的 DNS 服务器记录了整个 DNS 请求过程，并访问一个子域名来检查该子域名证书的 OCSP 请求。很明显，Chrome 并不会主动请求 OCSP 来检查证书状态，而 Firefox 则会。而且 Firefox 默认开启了 OCSP 查询，如下图所示：

那么，Chrome 是否有类似的选项呢？我在 Chrome 的设置项中找了很久，并没有找到这个选项。而且在 chrome://flags 页面下尝试寻找类似的设置项，同样没有找到。这是因为 Google 主动关闭了这个选项，认为这可能会泄露用户的隐私信息，并影响 Chrome 的网页加载速度。

实验#

通过前文，读者应该已经了解到在一般情况下，Chrome 不会主动检查证书状态。只要证书链完整且可以验证到根证书，一般都会被视为可信。而 Firefox 会通过 OCSP 来验证证书的状态，并根据该状态判断证书是否被吊销。那么为什么 Chrome 会这样呢？因为大多数 OCSP 网站使用的是 HTTP 协议，并没有使用 TLS 层（不可能请求一个 OCSP 网站时还要验证 OCSP 网站的证书，并递归请求它的 OCSP 信息）。如大家所知，HTTP 是明文的，任何人都可以检查没有 TLS 层的 HTTP 数据包。在这个过程中，用户的隐私可能会被泄露，这是 Google 考虑的合理因素。其他人可以通过检查 OCSP 请求了解某个用户访问了哪些网站，因为 OCSP 请求是特定的，每个 SSL/TLS 证书的 OCSP 信息都不相同。鉴于传统的 CRL 更新速度过慢，Google 自己维护了一个 CRL。其实和之前的 CRL 一样，也存在更新的时间差。

我的实验是这样的：我申请了一个针对自己子域名的 SSL/TLS 证书，并安装了该证书。然后分别使用 Chrome 和 Firefox 访问该子域名，当然 Firefox 会检查证书的吊销状态。接着我手动吊销了该证书，并再次分别使用 Chrome 和 Firefox 访问。Chrome 的访问是正常的，而 Firefox 则报告该证书已被吊销。因此，OCSP 是相当及时的。这也显示出了 Chrome 关闭 OCSP 证书验证的不安全性。

Chrome 开启验证 OCSP#

那么 Chrome 就真的无法开启 OCSP 验证么？经过一番搜索和测试，如果在建立如下两个目录 1

/etc/opt/chrome/policies/recommended

/etc/opt/chrome/policies/managed

并在 managed 目录写一个 JSON 文件，内容如下

Copy
{

"EnableOnlineRevocationChecks": true
}

就可以打开 Chrome 的 OCSP 质询，通过 DNS，可以检查到 Chrome 请求了 OCSP 网站，如图

讨论#

关于 Google 关闭 OCSP 的原因，我认为可能是考虑了速度因素。在整个 TLS 握手过程中，OCSP 的速度会显著影响整体握手速度。如果 OCSP 服务器过载或响应缓慢，会影响网站的加载速度。对于追求速度的 Google 来说，这是无法容忍的。因此，保护用户隐私可能只是一个附带的考虑因素。

同时，Google 还需要与竞争对手 Firefox 竞争。Firefox 更注重安全和隐私，因此默认开启了 OCSP。然而，在某些情况下，开启 OCSP 可能导致无法访问某些网站（例如，OCSP 信息错误或证书要求强制使用 OCSP Stapling，但网站未正确配置）。相比之下，Chrome 可以打开这些网站，这为 Chrome 建立了良好的声誉。

为了解决 OCSP 响应速度的问题，OCSP Stapling 技术被引入。Web 服务器可以提前从 OCSP 服务器获取自己证书的 OCSP 信息，并将其缓存起来。在 TLS 握手过程中，服务器可以直接将 OCSP Stapling 信息响应给客户端，从而节省了客户端单独去查询 OCSP 服务器的时间和延迟。值得注意的是，OCSP 信息是由 CA 的私钥签名的，因此一般不会存在伪造的问题。

然而，在验证过程中，Chrome 对于由 Web 服务器提供的 OCSP Stapling 信息似乎并不给予高优先级。Chrome 的验证优先级是先检查 Google 自己维护的 CRL，然后是 OCSP 查询，最后才考虑 OCSP Stapling 信息。这实际上违背了 OCSP Stapling 的初衷，因为本意是希望客户端直接使用 Web 服务器提供的已验证的 OCSP Stapling 信息。相比之下，Firefox 则能够愉快地接受并使用 Web 服务器提供的 OCSP Stapling 信息。我更新了 Chrome 114（Linux）之后，似乎修改了优先级，OCSP Stapling 为最高优先级。

在中国发生过 Let's Encrypt CA 的 OCSP 域名被污染的情况。由于许多网站使用了由 Let's Encrypt CA 颁发的证书，当 OCSP 域名受到污染时，导致大量 TLS 握手失败。这对访问这些网站的用户产生了一定的影响。这种情况迫使 Let's Encrypt CA 不得不更换 OCSP 域名，以解决该问题，并确保用户能够正常访问使用其证书的网站。

综上，我认为 Chrome 主动关闭 OCSP 是为了和 Firefox 竞争，毕竟给用户的印象是 Chrome 快，Firefox 慢。

希望 Firefox 一直和 Chrome 竞争下去！

引用#

此文由 Mix Space 同步更新至 xLog
原始链接为 https://www.timochan.cn/posts/study/ocsp_certificate_status_verification_exploration

Footnotes#

https://chromeenterprise.google/policies/?policy=EnableOnlineRevocationChecks ↩