Crypt32 证书吊销列表 (CRL) 语义
Crypt32 支持用于联机吊销检查的证书吊销列表 (CRL) 语义。 本文介绍了 Crypt32 如何使用 CRL 进行联机吊销检查,以及如何使用 CRL 预提取和分区来提高性能。
简介
启用联机吊销时调用 Crypt32 CertGetCertificateChain API 时,它将尝试检索有效的 OCSP 响应或 CRL 的时间,如下所示:
- 检查握手中是否包含有效的装订 OCSP 响应。
- 检查用户 Cryptnet URL 缓存中是否有时间有效的 OCSP 响应或 CRL。
- 检查系统存储中是否有有效的 CRL 时间,例如 HKLM\CA。
- 对于使用者证书的 AIA 扩展中的 OCSP URL,尝试从 OCSP 服务器下载 OCSP 响应。
- 若要成功,请将 OCSP 响应添加到用户的 Cryptnet URL 缓存。
- 对于使用者证书中的 CRL CDP 扩展,尝试从证书颁发机构 (CA) 的 CRL 服务器下载 CRL。
- 若要成功,请将 CRL 添加到用户的 Cryptnet URL 缓存。
对于添加到 Cryptnet URL 缓存的 CRL,如果 CRL 具有以下扩展名,则会在 CRL 过期之前检索下一个 CRL:“1.3.6.1.4.1.311.21.4”(下一个 CRL 发布)。 通过添加此扩展,证书验证期间只会进行初始 CRL 下载。 有关 Crypt32 如何使用此扩展来预提取下一个 CRL 的详细信息,请参阅 CRL 预提取 部分。
如果 CA 颁发大量证书,则 CRL 上吊销的条目数也可能变得很大,从而增加 CRL 的大小。 为了保持 CRL 的大小处于检查状态,Microsoft建议并支持通过添加到下载的 CRL 的“2.5.29.28”(发出分发点)扩展进行 CRL 分区。 有关 Crypt32 如何通过此扩展支持 CRL 分区的详细信息,请参阅 CRL 分区 部分。
CA 正在考虑放弃对 OCSP 的支持,并且仅支持 CRL 才需要考虑这会对调用启用了联机吊销的 CertGetCertificateChain API 的应用程序产生的影响:
- 在第一次验证中,调用应用程序将执行按需 CRL 下载,并会阻止 API 完成,直到下载 CRL。
- 对于大容量 TLS 服务器,CA 的 CRL 服务器将有相应的大容量下载。
- 如果 CRL 变大,它将直接影响到服务器能够处理大量下载。
- CRL 的大小可以通过支持已分区 CRL 来限制。
- 后续验证将使用缓存的 CRL,直到 CRL 过期。 CRL 过期后,将针对下一次验证重复上述内容。
- 可以通过添加下一个 CRL 发布扩展来避免此按需 CRL 下载。
以下部分提供有关 CRL 预提取和分区的信息,以改进仅使用 CRL 的联机吊销性能。
CRL 预提取
编码的 CRL 具有以下两个字段,指示 CRL 何时发布,以及客户端在需要检索下一个已发布的 CRL 之前可以缓存多长时间。
ThisUpdate GeneralizedTime,
NextUpdate GeneralizedTime OPTIONAL,
如果 NextUpdate 缺失,则这是要发布的最后一个 CRL,永远不会过期。
CRL 可能包含“1.3.6.1.4.1.311.21.4”(下一个 CRL 发布)扩展,该扩展也编码为 GeneralizedTime。 如果存在此扩展,Crypt32 将尝试在此 PublishTime 之后和 NextUpdate 之前预提取下一个已发布的 CRL,如下所示:
给定, PublishPeriod = NextUpdate – PublishTime
. 以下三个配置参数用于确定 PreFetchPeriod 的开始和结束:
- AfterPublishPreFetchDivisor
- PreFetchPeriod 的开始通过将 PublishPeriod 除以此除数,在 PublishTime 之后延迟。
- 默认值为 10
- BeforeNextUpdatePreFetchDivisor
- PreFetchPeriod 完成之前,将 PublishPeriod 除以此除数。
- 默认值为 20
- MinPreFetchPeriod
- 给定,
PreFetchPeriod = PreFetchPeriodFinishTime – PreFetchPeriodStartTime
. 仅当 PreFetchPeriod 超过此最小值时,才启用预提取。 - 默认值为 1 小时
- 给定,
鉴于上述计算的 PreFetchPeriod,会在此 PreFetchPeriod 中选取一个随机时间,以便每个客户端从服务器预提取和下载已发布的 CRL。
一些示例时间和相应的 PreFetchPeriod 使用默认配置值。
CRL 有效期为两天,每天发布:
ThisUpdate: Nov 05 08:00
NextUpdate: Nov 07 08:00
PublishTime: Nov 06 08:00
PublishPeriod = 24 hours
PreFetchPeriodStartTime = PublishTime + 24/10 (2.4 hours)
PreFetchPeriodFinishTime = NextUpdate – 24/20 (1.2 hours)
PreFetchPeriod = Nov 06 10:24 .. Nov 07 06:48 = 20:24
Clients would randomly pre-fetch in the above PreFetchPeriod.
CRL 有效期为 8 天,每四天发布一次:
ThisUpdate: Nov 03 08:00
NextUpdate: Nov 11 08:00
PublishTime: Nov 07 08:00
PublishPeriod = 96 hours
PreFetchPeriodStartTime = PublishTime + 96/10 (9.6 hours)
PreFetchPeriodFinishTime = NextUpdate – 96/20 (4.8 hours)
PreFetchPeriod = Nov 07 17:36 .. Nov 11 03:12 = 81:36
Clients would randomly pre-fetch in the above PreFetchPeriod
注意
如果客户端未使用预提取的 CRL,则上述预提取将停止,直到客户端为此 CRL 启动新的按需下载。
CRL 分区
本部分提供有关 Crypt32 如何支持 CRL 分区的信息。
示例
下面是用于 CRL 分区的常用格式化 CDP 和标识提供者 (IDP) 扩展的示例。
对于从 CA 颁发的证书的第一个分区:
Cert CDP:
[1]CRL Distribution Point
Distribution Point Name:
Full Name:
URL=http://crl.godaddy.com/first.crl
CRL IDP:
Distribution Point Name:
Full Name:
URL=http://crl.godaddy.com/first.crl
Only Contains User Certs=No
Only Contains CA Certs=No
Indirect CRL=No
对于从 CA 颁发的证书的第二个分区,请指向 CDP 和 IDP 中的不同 CRL:
Cert CDP:
[1]CRL Distribution Point
Distribution Point Name:
Full Name:
URL=http://crl.godaddy.com/second.crl
CRL IDP:
Distribution Point Name:
Full Name:
URL=http://crl.godaddy.com/second.crl
Only Contains User Certs=No
Only Contains CA Certs=No
Indirect CRL=No
正如你所看到的,CDP 和 IDP 中使用了同一个 http CRL URL。 此外,分区 CRL 由 CA 直接签名,适用于 CA 和最终用户证书。
下一部分详细介绍了 IDP 和 CDP 扩展的 ASN.1 编码以及 Crypt32 支持的内容。
详细信息
这是颁发分发点(IDP)扩展(“2.5.29.28”)的 ASN.1:
--------------------------------------------
-- CRL Issuing Distribution Point Extension
--------------------------------------------
IssuingDistributionPoint ::= SEQUENCE {
issuingDistributionPoint [0] EXPLICIT DistributionPointName OPTIONAL,
onlyContainsUserCerts [1] IMPLICIT BOOLEAN DEFAULT FALSE,
onlyContainsCACerts [2] IMPLICIT BOOLEAN DEFAULT FALSE,
onlySomeReasons [3] IMPLICIT ReasonFlags OPTIONAL,
indirectCRL [4] IMPLICIT BOOLEAN DEFAULT FALSE
} --#public—
DistributionPointName ::= CHOICE {
fullName [0] IMPLICIT GeneralNames,
nameRelativeToCRLIssuer [1] IMPLICIT RelativeDistinguishedName
}
GeneralNames ::= SEQUENCE OF GeneralName
GeneralName ::= CHOICE {
otherName [0] IMPLICIT OtherName,
rfc822Name [1] IMPLICIT IA5STRING,
dNSName [2] IMPLICIT IA5STRING,
x400Address [3] IMPLICIT SeqOfAny,
directoryName [4] EXPLICIT NOCOPYANY, -- really Name
ediPartyName [5] IMPLICIT SeqOfAny,
uniformResourceLocator [6] IMPLICIT IA5STRING,
iPAddress [7] IMPLICIT OCTETSTRING,
registeredID [8] IMPLICIT EncodedObjectID
}
如果 CRL 具有 IDP,Windows 客户端将按如下所示继续操作:
- 忽略 IDP:
- onlySomeReasons
- indirectCRL
- 仅支持具有 fullName 选项的 IDP。
- CRL CDP 还必须具有 fullName 选项。
- 如果 onlyContainsUserCerts 或 onlyContainsCACerts:
- 使用证书的基本约束扩展来确定 IDP 是否适用于证书。
这是证书中 CDP 扩展的 ASN.1:
--------------------------------------------
-- CRL Distribution Points Extension
--------------------------------------------
CRLDistributionPoints ::= SEQUENCE OF DistributionPoint
DistributionPoint ::= SEQUENCE {
distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL,
reasons [1] IMPLICIT ReasonFlags OPTIONAL,
cRLIssuer [2] IMPLICIT GeneralNames OPTIONAL
}
DistributionPointName see above
Windows 客户端将:
- 循环访问 IDP 的 GeneralNames 序列,直到匹配 CDP 名称:
- 循环访问 CDP 的 DistributionPoint 序列:
- 跳过 CDP 分发点 ,并具有:
- 原因
- cRLIssuer
- 如果 CDP DistributionPoint 没有适用于 DistributionPointName 的完整名称选项,请跳过 CDP DistributionPoint。
- 循环访问 CDP 的 GeneralNames 序列:
- 检查 IDP 和 CDP GeneralName 是否匹配
- 如果 IsSameGeneralName(),我们有匹配项,CRL 可用于使用者证书。
- 检查 IDP 和 CDP GeneralName 是否匹配
- 跳过 CDP 分发点 ,并具有:
- 循环访问 CDP 的 DistributionPoint 序列:
IsSameGeneralName(IDP_GeneralName,CDP_GeneralName)
IDP 和 CDP 必须具有相同的 GeneralName 选项。 对于同一选项,根据选择比较 IDP 和 CDP 名称:
- rfc822Name
- 不区分大小写的字符串比较。 无 %字符规范化。
- dNSName
- 不区分大小写的字符串比较。 无 %字符规范化。
- uniformResourceLocator (URL)
- 不区分大小写的字符串比较。 无 %字符规范化。
- otherName
- 比较 OID 和 OID 特定的二进制值。
- registeredID
- 比较 OID。
- directoryName
- 比较编码的名称字节。
- iPAddress
- 比较编码的 OCTET 字节。
- x400Address
- 不支持。
- ediPartyName
- 不支持。
预期是将使用 uniformResourceLocator GeneralName 选项。