写点什么

密码学系列之: 在线证书状态协议 OCSP 详解

作者:程序那些事
  • 2022 年 5 月 21 日
  • 本文字数:3872 字

    阅读完需:约 13 分钟

密码学系列之:在线证书状态协议OCSP详解

简介

我们在进行网页访问的时候会跟各种各样的证书打交道,比如在访问 https 网页的时候,需要检测 https 网站的证书有效性。


OCSP 就是一种校验协议,用于获取 X.509 数字证书的撤销状态。它是为了替换 CRL 而出现的。


本文将会详细介绍 OCSP 的实现和优点。

PKI 中的 CRL

我们知道在 PKI 架构中,CA 证书是非常重要的组件,客户端通过 CA 证书来验证服务的可靠性。对于 CA 证书本身来说在创建的时候是可以指定过期时间的。这样证书在过期之后就不可以使用,需要申请新的证书。


但是只给证书指定过期时间是不够的,比如我们因为业务的需求,需要撤销证书怎么办呢?


PKI 中提供了一个叫做 CRL(certificate revocation list)的机制,用来维持被废除的证书列表。


这个 CRL 是由 CA 来颁发的,一般是在证书过期之前生成的。因为如果证书已经过期了,那么这个 CRL 是无意义的。


对于 CRL 本身来说,它是一个证书列表,里面证书的格式通常也使用的是 X.509。


CRL 一般是由发布证书的 CA 来维护和发布的,发布 CRL 的组件叫做 CRL issuer,通常来说 CRL issuer 和 CA 是同一个服务,但是你也可以根据需要将 CRL issuer 和 CA 进行拆分。


CRL 是由 CA 定时来发布的,当然你也可以按照需要在需要撤销某个 CA 证书的时候重新发布 CRL。所有的 CRL 都有过期时间,在这个过期时间之内,客户端可以根据 CRL 中的签名,去 CA 验证 CRL 的有效性,从而防止 CRL 的伪造。

CRL 的缺点

那么 CRL 有什么缺点呢?


首先 CRL 维持的是一个撤销的证书列表,为了保证系统的有效性,客户端在每次校验 CA 证书有效性的时候,都需要从 CA 服务器中获取这个 CRL。然后通过 CRL 来校验对应的 CA 证书状态。


如果每次都去拿这个 CRL,就有可能会有下面几个问题。


第一个问题是,如果 CRL 不可用,那么客户端就拿不到这个 CRL,也就无法校验 CA 证书的状态,从而造成服务不可用。


另外一个问题是,如果要撤销的证书比较多的话,这个 CRL 可能会比较大,从而造成网络资源的浪费。


最后一个问题是 PKI 证书体系本身的目的是建立一个可以自我校验的,不依赖于在线服务的安全体系,如果每次都要在线获取 CRL 的话,就是去了 PKI 的这一优势。

CRL 的状态

虽然 CRL 维持的是一个撤销证书列表,但是这个列表中证书的状态还是有所不同的。


CRL 中证书的状态有两种,第一种就是证书已经被撤销了,比如证书的颁发机构 CA 发现之前的颁布的证书是错误的,或者因为其他的原因如私钥泄露导致原来的证书不够安全,需要将证书撤回。或者证书机构因为未遵守某些策略导致证书被吊销等,都需要将之前的证书设置为撤销状态。


还有一种状态是一个临时撤销的状态,这里叫做 Hold 状态,它表示证书暂时是无效的,比如在用户没有确定私钥是否丢失的情况下。当用户最终找回了私钥,则这个证书还是可以被恢复的。

OCSP 的工作流程

既然 CRL 有这么多缺点,所以一个用来替代 CRL 的 OCSP 协议出现了。


我们先来看一下 OCSP 的工作流程。


假如 A 和 B 要进行使用 PKI 进行通讯。为了保证通讯的安全性,A 将自己的公钥发给 B,并告诉 B,这是我的公钥,你可以用这个公钥来校验我发送给你的消息。


B 在收到 A 的公钥之后,并不能确定 A 的公钥就是正确的,没有被篡改的。于是从 A 的公钥中提取出 serial number,并将其封装到一个'OCSP request'中发给 CA 服务器。


CA 服务器中的 OCSP responder 读取到了'OCSP request'请求,并从中提取出 A 的公钥的 serial number。OCSP responder 从 CA 服务器的数据库中查询这个 serial number 是否在这个数据库被撤销的列表中。


如果发现不在,那么意味着 A 的公钥仍然是有效的,OCSP responder 将会发送一个签名后的 OCSP response 给 B。


B 通过使用 CA 服务器的公钥验证 OCSP response 的有效性,从而确认 A 的公钥仍然有效 。


最后 B 使用 A 的公钥和 A 进行通讯。

OCSP 的优点

从上面的 OCSP 的工作流程我们可以大概总结出下面几个 OCSP 相对于 CRL 的优点。


首先 OCSP 响应的数据量要比 CRL 要小,所以对网络的要求和压力更少。


另外因为 OCSP 响应要解析的数据更少,所以 OCSP 客户端的实现要比 CRL 更加简单。


虽然因为 CRL 的各种缺点,在 web 环境中已经不再被使用,而是被更加高效的 OCSP 替换,但是 CRL 仍然被运行在 CA 的其他环境中。

OCSP 协议的细节

OCSP 协议是在 RFC 6960 中定义的。


OCSP 协议可以分为请求协议和响应协议两部分,接下来分别来进行介绍。

OCSP 请求

一个 OCSP 请求需要包含协议版本号,请求服务,要校验的证书 identifier 和可选的扩展部分。


OCSP responder 在接收到 OCSP 的请求之后,会去校验 OCSP 消息的有效性,如果消息有问题则会返回异常,否则的话会根据请求的服务进行处理。


OCSP 请求如果用 ASN.1(Abstract Syntax Notation One)抽象语法标记这可以如下表示:


   OCSPRequest     ::=     SEQUENCE {       tbsRequest                  TBSRequest,       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
TBSRequest ::= SEQUENCE { version [0] EXPLICIT Version DEFAULT v1, requestorName [1] EXPLICIT GeneralName OPTIONAL, requestList SEQUENCE OF Request, requestExtensions [2] EXPLICIT Extensions OPTIONAL } Signature ::= SEQUENCE { signatureAlgorithm AlgorithmIdentifier, signature BIT STRING, certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
Version ::= INTEGER { v1(0) }
Request ::= SEQUENCE { reqCert CertID, singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
CertID ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, issuerNameHash OCTET STRING, -- Hash of issuer's DN issuerKeyHash OCTET STRING, -- Hash of issuer's public key serialNumber CertificateSerialNumber }
复制代码


ASN.1 是一个接口描述语言,通过 ASN.1,我们可以很清晰的描述数据的格式信息。


一个 OCSPRequest 是由可选择签名的 OCSP 请求 tbsRequest 和对应的签名 optionalSignature 组成的。


其中 TBSRequest 中包含了版本号,OCSP requestor 的名字,证书的状态列表 requestList,可选的扩展数据这几项组成的。

OCSP 响应

对于 OCSP 的响应来说,根据传输协议的不同它的结构也是不同的。但是所有的响应都应该包含 responseStatus 字段表示请求的处理状态。


OCSP 响应用 ASN.1 格式来表示如下所示:


   OCSPResponse ::= SEQUENCE {      responseStatus         OCSPResponseStatus,      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
OCSPResponseStatus ::= ENUMERATED { successful (0), -- Response has valid confirmations malformedRequest (1), -- Illegal confirmation request internalError (2), -- Internal error in issuer tryLater (3), -- Try again later -- (4) is not used sigRequired (5), -- Must sign the request unauthorized (6) -- Request unauthorized }
ResponseBytes ::= SEQUENCE { responseType OBJECT IDENTIFIER, response OCTET STRING }
复制代码


responseStatus 是响应的状态,responseBytes 是可选的响应结果。


这里的 response 是一个 BasicOCSPResponse 对象的 DER 编码:


   BasicOCSPResponse       ::= SEQUENCE {      tbsResponseData      ResponseData,      signatureAlgorithm   AlgorithmIdentifier,      signature            BIT STRING,      certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
复制代码

OCSP stapling

可以看到 OCSP 需要客户在需要查看证书是否被吊销的时候,需要向 OCSP responser 请求,以确认证书的有效性。


但是这种方式实际上泄露了用户的隐私信息,因为 OCSP responser 知道了客户端需要校验的证书,就知道客户端正在访问的网站。


于是引入了 OCSP stapling 来解决这个问题。


那么什么是 OCSP stapling 呢?


OCSP stapling 是直接将 OCSP 证书放到客户端要访问的 web 服务器上,因为 OCSP 证书是添加了时间戳和数字签名的,所以可以保证其正确性。


这些 OCSP 证书会在客户端和 web 端建立 SSL 握手的时候就包含在 OCSP 响应中。


这样客户端不需要单独和 CA 建立额外的连接,从而提高了性能。


OCSP stapling 需要在服务器端主动开启。


如果你用的是 apache 服务器,首先需要版本大于 2.3.3。


然后需要在.conf 文件中的<VirtualHost></VirtualHost> block 外部添加:


SSLStaplingCahe shmcb: /tmp/stapling_cache(128000)
复制代码


然后在<VirtualHost></VirtualHost> block 的内部添加:


SSLUseStapling On
复制代码


如果你用的是 nginx,首先需要版本大于 1.3.7。


然后在 nginx 的配置文件server {} block 中添加:


ssl_stapling on;ssl_stapling_verify on;
复制代码


如果你想验证一个网站是否开启了 OCSP stapling,可以到https://entrust.ssllabs.com/网站中进行查询:


在这个网站中,你可以输入任何要查询的网站地址,然后可以得到下面的信息:



可以看到这个网站是开启了 OCSP stapling 的。

总结

OCSP 和 OCSP stapling 是非常有用的证书撤销校验协议,已经被广泛的使用。大家可以检查一下自己的网站有没有用到哦。


更多内容请参考 http://www.flydean.com/43-pki-ocsp/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 刚刚阅读数: 2
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
密码学系列之:在线证书状态协议OCSP详解_密码学_程序那些事_InfoQ写作社区