CRL 基础知识:先搞懂证书吊销这件事
你想想看,一台服务器用的证书明明还没到期,为什么突然就不能用了?
原因很简单——证书被吊销了。就像信用卡丢了,你得挂失一样。证书密钥泄露、证书颁发错误、域名所有权变更……这些场景下,CA(证书颁发机构)必须把证书提前作废。
今天我们就从最基础的东西聊起,什么叫 CRL,它到底长什么样,怎么用。
为什么需要 CRL?
X.509 证书本身是有有效期的,通常 1 年或 2 年。但在没到期之前,有些特殊情况必须让证书提前失效:
- 私钥泄露或怀疑泄露
- 证书信息有误(域名、组织名等)
- 员工离职、域名废弃
- CA 自身被入侵
CA 必须把这类证书“拉黑”,让客户端在验证时拒绝放行。这种方式就是证书吊销。而 CRL(Certificate Revocation List,证书吊销列表) 就是 CA 定期发布的一个“黑名单”文件。
CRL 的定义和作用
严格按照 RFC 5280 的说法,CRL 是一个由 CA 签名的时间戳列表,包含了所有已吊销但未到期的证书序列号。说白了,它就是一张经过数字签名的“作废清单”。
它的核心作用有两条:
- 告知状态:告诉所有客户端,哪些证书已经不可信。
- 形成证据:CRL 由 CA 签名,不可抵赖,可以用于审计。
我在项目中遇到过好几次,运维同学以为证书到期前就是安全的,结果私钥泄露导致中间人攻击,就是因为没有及时刷新 CRL,系统还在信任已吊销的证书。
CRL 长什么样?
RFC 5280 规定的 CRL 使用 ASN.1 语法编码,实际存储一般是 DER 或 PEM 格式。你用 OpenSSL 命令可以把它解析出来看。
提取 CRL 并查看内容:
# 下载 CRL 文件
curl -O http://crl.example.com/ca.crl
# 查看 CRL 内容(DER 格式)
openssl crl -in ca.crl -inform DER -text -noout
# 如果是 PEM 格式
openssl crl -in ca.crl -inform PEM -text -noout
解析出来的内容大概长这样:
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: /C=CN/ST=Beijing/L=Haidian/O=Example CA
Last Update: Jun 1 10:00:00 2025 GMT
Next Update: Jun 8 10:00:00 2025 GMT
CRL extensions:
X509v3 Authority Key Identifier: ...
X509v3 CRL Number: 12345
Revoked Certificates:
Serial Number: 0xABCDEF1234567890
Revocation Date: May 28 14:30:00 2025 GMT
CRL Reason Code: keyCompromise
Serial Number: 0x1122334455667788
Revocation Date: May 29 09:00:00 2025 GMT
CRL Reason Code: affiliationChanged
这里最关键是几个字段:
| 字段 | 含义 | 运维关注点 |
|---|---|---|
| Issuer | 签发该 CRL 的 CA 名称 | 必须与要验证的证书的签发者一致 |
| Last Update | 本次 CRL 发布时间 | 客户端拿到的是否最新版 |
| Next Update | 下次 CRL 更新时间 | 过了这个时间,CRL 失效,必须重新拉取 |
| Serial Number | 被吊销证书的序列号 | 比对客户端证书的序列号是否命中 |
| Revocation Date | 吊销发生的时间戳 | 用于判定吊销发生的先后顺序 |
| CRL Reason Code | 吊销原因 | 常见:keyCompromise、caCompromise、superseded、cessationOfOperation |
CRL 的分发与获取
CA 不会主动把 CRL 推送给你,需要你自己去拉。证书里通常会内嵌一个 CRL Distribution Point(CRL 分发点) 的 URL,告诉你上哪儿下载。
查看证书中的 CRL 分发点:
openssl x509 -in server.crt -text -noout | grep -A 4 "CRL Distribution Points"
输出类似这样:
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.example.com/ca.crl
嗯,这里要注意,很多企业 CA 会有多个分发点,比如同时提供 HTTP 和 LDAP 两种方式,甚至还有 OCSP 替代方案。
CRL 与 OCSP 的区别
CRL 有一个天生的短板——它是个静态列表。CA 每隔一段时间(比如 7 天)才发布一次新版本。客户端拉到的 CRL,有效期覆盖整整一段时间。如果某个证书刚被吊销,CRL 是来不及同步的。
为了解决这个问题,RFC 2560 定义了 OCSP(在线证书状态协议)。OCSP 可以实时查询单个证书的状态,不需要下载整个列表。
| 对比维度 | CRL | OCSP |
|---|---|---|
| 查询方式 | 下载整个列表,本地匹配 | 发送请求,查询单个证书 |
| 实时性 | 延迟一次发布周期(几十小时到几天) | 实时查询,毫秒级响应 |
| 网络开销 | 列表可能很大(几 MB 到几十 MB) | 请求体积小,约几百字节 |
| 离线能力 | 支持,缓存 CRL 即可 | 必须联网 |
| 部署复杂度 | 低,架个静态文件服务就能跑 | 需要 OCSP 响应器,配置复杂 |
现实中,大多数浏览器和服务器其实是两者都支持。但我个人建议在生产环境里优先用 OCSP,实时性好太多。CRL 可以作为兜底方案——当 OCSP 服务挂了,客户端还能退回来查 CRL。
一张图看清 CRL 在 PKI 里的位置
CRL 分发失败会怎样?
讲到这里,很多人会问:如果 CRL 拉不到,客户端会拒绝连接吗?
不一定。这取决于客户端的策略。有些严格的策略(比如金融行业)规定:如果无法获取 CRL 或 OCSP 响应,直接拒绝信任,这叫“hard-fail”。但大部分浏览器默认是“soft-fail”,即拉不到 CRL 就忽略,继续信任证书——说白了,拉不到就当没吊销。
所以我建议企业环境里,一定要配置硬失败策略,让 CRL 抓取失败时直接拒绝连接。虽然会牺牲一些可用性,但安全性是实打实的。
小结一下
- CRL 是 CA 签名的已吊销证书列表,用于客户端校验证书状态。
- 核心字段包括序列号、吊销时间、吊销原因、发布有效期。
- CRL 分发点通常内嵌在证书扩展里,支持 HTTP 或 LDAP 方式下载。
- CRL 有延迟问题,实时场景推荐搭配 OCSP 使用。
- CRL 获取失败时的行为策略(hard-fail vs soft-fail)直接决定系统安全水位。