3、CRL分发机制:分发点与增量CRL

CRL 这东西,说白了就是证书吊销的黑名单。但黑名单怎么发给客户端?总不能每个CA把几百万条记录塞一个文件里吧?那网络和客户端都得崩溃。所以就有了分发点(CDP)和增量CRL(Delta CRL)这套机制。我记得刚入行那年,客户抱怨证书验证慢,一查才发现他们几百台服务器都在下载同一个300MB的完整CRL——嗯,那就是没用好CDP。

3.1 CRL分发点(CDP)

每个CRL的签名证书里都会有一个扩展,叫 CRL Distribution Points(CDP)。它告诉客户端:“想查吊销信息?去这些地址下载”。我建议所有生产环境的证书都至少配两个分发点——一个HTTP,一个LDAP。万一HTTP服务挂了,LDAP还能顶上。

核心要点: CDP 是证书里的 URL 列表,不是独立的服务器。客户端通过 CDP 找到 CRL 文件。

CDP 扩展的结构长这样(RFC 5280 的定义):

CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint

DistributionPoint ::= SEQUENCE {
    distributionPoint    [0] DistributionPointName OPTIONAL,
    reasons              [1] ReasonFlags OPTIONAL,
    cRLIssuer            [2] GeneralNames OPTIONAL
}

字段说明:

字段作用
distributionPointURL 或目录名,客户端通过它定位 CRL 文件
reasons可选,指定该分发点只负责哪些吊销原因(如密钥泄露、CA 泄露)
cRLIssuer可选,当 CRL 由另一个权威签发时,指明签发者

我在项目中遇到过一个坑:某家大厂把 CDP 指向了内网地址,结果互联网客户端验证失败——因为它解析不了内网域名。后来我们强制要求 CDP 必须使用公网可访问的 HTTP URL,且不能写 IP 地址,必须写域名。

3.2 增量CRL(Delta CRL)

完整CRL体积大、更新慢。增量CRL只包含上一次完整CRL发布以来新吊销的证书。客户端先下载完整CRL,之后定期拉增量CRL合并即可。这个机制能大幅降低网络开销,尤其适合大规模 PKI。

增量CRL的更新周期通常很短(比如每小时一次),而完整CRL可以每天一次。我建议:

  • 完整CRL:有效期 24 小时,每天凌晨生成
  • 增量CRL:有效期 1 小时,每整点生成

客户端逻辑:先判断本地缓存的完整CRL是否过期,若过期则下载完整CRL;若未过期,则下载所有比上次下载时间更新的增量CRL,合并后使用。

技巧: 增量CRL的名字可以用完整CRL的序列号加上时间戳,比如 crl_20250301_full.crl 和 crl_20250301_delta_10.crl,方便客户端按时间戳排序增量文件。

3.3 增量CRL与完整CRL的对比

对比项完整CRL增量CRL
文件体积大(全量吊销证书)小(仅新增吊销)
更新频率低(每日~每周)高(每小时~数小时)
生成开销高(全量扫描数据库)低(仅扫描增量数据)
客户端复杂度低(一次下载即用)高(需维护合并状态)
推荐场景中型 PKI(千级证书)大型 PKI(万级以上)

我曾经帮一家金融机构设计CRL分发方案。他们每天要吊销几百张证书,完整CRL接近200MB。客户端全是移动设备,每月流量扛不住。改成增量CRL后,客户端每次只下载几百KB,体验好多了。

3.4 分发点选择策略

  1. 负载均衡:多个 CDP 分布在不同的数据中心,客户端随机选一个下载
  2. 地理位置就近:CDP 使用 CDN 或 GeoDNS,让客户端去最近的节点
  3. 协议多样性:至少一个 HTTP、一个 LDAP、一个 HTTP Redirect
  4. 冗余覆盖:每个分发点独立,不要所有 CDP 指向同一台服务器

警告: 不要把所有 CDP 写成一个 DNS 域名下的多个路径。如果该域名整体挂了,所有 CDP 都不可用。每个 CDP 应使用独立的域名或 IP。

3.5 知识结构图

下面这张图概括了CRL分发机制的核心关系:证书持有者、CA、分发点、客户端之间的交互。

CRL分发机制核心流程图 CA(证书颁发机构) 完整CRL(Base CRL) 增量CRL(Delta CRL) CDP 分发点 (HTTP / LDAP / FTP) 客户端(验证者) 下载CRL → 验证证书状态 说明: 1. CA 生成完整CRL(周期较长)和增量CRL(周期短)。 2. 所有CRL文件发布到多个CDP分发点(分布式部署)。 3. 客户端从CDP获取最新CRL(优先增量+完整合并)。

3.6 实际操作中的避坑指南

我这些年踩过不少跟CRL分发有关的雷,挑几个典型的说说:

  • CDP 被防火墙拦截:曾经有客户把CRL文件放在测试网段,生产客户端下载失败——证书验证直接挂起,业务全停了。后来我们在每个CDP URL后面加了一句 source ip = production 的ACL允许列表。
  • 增量CRL不合并导致假阳性:有个客户端库实现有bug,只拿了增量CRL没合并完整CRL,结果把一个早就撤销的证书当成有效。所以务必在客户端侧实现合并逻辑,或者干脆用OCSP代替。
  • CRL 签名验证失败:CA轮换密钥后,如果旧CRL的签名公钥没同步到客户端,客户端会拒绝所有CRL。我建议保留至少两个版本的CA证书用于CRL验证。

小提示: 如果你们的PKI规模不大(少于5000张证书),其实没必要上增量CRL。完整CRL每天更新一次,配合CDP的HTTP缓存,体验已经够好了。增量CRL的客户端实现复杂度高,小规模场景得不偿失。

3.7 本章小结

CRL分发机制的核心就三件事:CDP定义CRL的获取路径、增量CRL降低传输开销、客户端正确合并。设计时记住“分布式、冗余、协议多样”这九个字。下回遇到证书验证慢的问题,先查CDP有没有配对,再查增量CRL有没有正确合并——八成能解决问题。