数字证书的相关专业名词(中)---根证书和CRL,以及java中CRL的获取和验
上篇文章我们主要了解了PKI中的数字证书和PKCS,这篇文章我们主要了解一下根证书,以及OCSP和CRL。
在公钥基础设施(PKI)中,根证书是整个数字证书体系的最高级别证书。根证书由受信任的第三方机构(CA)颁发,用于验证其他证书以及建立信任链。当您收到一个数字证书时,您可以跟踪证书链来验证该证书是否有效。证书链是一组数字证书,其中包括一个或多个中间证书和一个根证书。每个证书都由其颁发机构签名,并包含颁发机构的公钥。通过跟踪证书链,您可以验证目标证书的所有者身份以及该证书是否受信任。证书链中的最后一个证书是根证书,它是唯一一个不需要由其他证书签名的证书。根证书只能由被认可的CA机构颁发,并且默认情况下存储在浏览器、操作系统和应用程序的信任存储库中。使用根证书,您可以验证中间证书和服务器证书的有效性。如果您信任根证书所属的CA机构,则可以信任整个证书链中的所有证书。总之,在PKI中,根证书是信任链中的顶级证书。它们用于验证其他证书并建立信任关系,因此它们对于确保安全通信至关重要。 证书链(Certificate Chain)是由数字证书构成的一系列链接,其中每一个数字证书都被另一个数字证书所签名认证。这些数字证书中最顶层的证书称为“根证书(Root Certificate)”,并且没有上级证书对其进行认证。它是由数字证书颁发机构(CA)签署的自己的公钥。根证书可以用于验证其他数字证书的有效性。当客户端访问一个使用SSL/TLS协议进行加密通信的网站时,它将会收到该网站的数字证书。该数字证书中包含了该网站的公钥和其它信息。客户端通过验证该数字证书的有效性,来确保与该网站进行的通信是安全可靠的。如果该数字证书无效或被篡改,则客户端将不信任该证书,并且停止与该网站进行通信。在验证数字证书的有效性时,客户端会遍历证书链上的所有数字证书,并且检查每个数字证书是否是由另一个数字证书所签名认证的。如果证书链上存在任何一个数字证书验证失败,则整个数字证书链都会被视为无效的。并且,客户端需要使用与之匹配的根证书来检查数字证书链的完整性和可信度。如果根证书无效或被篡改,则整个数字证书链将被视为不可信,并且通信将被终止。因此,证书链是确保数字证书有效性的重要组成部分,它可以帮助保护用户数据的安全和隐私。 CRL代表证书撤销列表(Certificate Revocation List),它是一种用于检查数字证书是否已被吊销的机制。CRL通常由证书颁发机构(CA)创建,其中包含已吊销数字证书的序列号。数字证书可能会被吊销,例如在证书所有者私钥泄露或证书信息被篡改时,CA可能会吊销该证书。当客户端接收到数字证书时,可以通过下载和验证与该数字证书相关的CRL来确认其是否已被吊销。使用CRL进行数字证书撤销检查时,客户端必须从CA获取最新的CRL,并且定期地更新本地的CRL。客户端可以通过验证数字证书的序列号是否出现在CRL中来检查数字证书的有效性。CRL有一些限制,例如CA必须定期创建和发布新的CRL,否则数字证书的吊销状态将无法得到及时更新。另外,大型CRL文件可能会导致网络延迟和性能问题。随着OCSP(Online Certificate Status Protocol)的出现,越来越多的系统开始采用OCSP来替代CRL进行数字证书状态检查。相比于CRL,OCSP更加灵活高效,并且不需要下载整个CRL文件即可完成数字证书状态检查。 在java中,我们可以通过证书的X509形式类X509Certificate去获取CRL地址,步骤如下
获取证书中的扩展信息: 其中2.5.29.31是X.509标准中定义的证书扩展之一,也称为CRL Distribution Points扩展。该扩展用于指定证书撤销列表(CRL)的位置,以便验证人员可以在验证证书时检查该证书是否已被撤销。CRL Distribution Points扩展包含一个或多个分发点,每个分发点都包含一个或多个CRL地址,其中可以获取到对应证书的CRL列表。java中也可以通过以下方法获取,同样也是2.5.29.31
解码扩展信息,首先创建一个新的ASN1InputStream对象,用于读取传递的字节数组参数crlDistributionPointsExtension。 然后,将扩展值包装在一个ASN1OctetString对象中,这可以通过在ASN1InputStream对象上调用readObject()来获取。接下来,使用ASN1OctetString对象的八位字节创建一个新的ASN1InputStream对象,并再次调用readObject()以获取表示CRL Distribution Points扩展的ASN1Primitive对象。 3.从CRL分发点扩展中获取CRL地址.
①首先通过之前的ASN1Primitive对象获取CRLDistPoint,CRLDistPoint是X.509证书中的一个扩展字段,它用于指定可撤销证书列表(CRL)的分发点。
②接着通过CRLDistPoint类中的getDistributionPoints()方法用于获取CRL分发点。具体来说,它返回一个DistributionPoint数组,其中包含了所有在CRLDistPoint扩展字段中找到的CRL分发点。
③然后通过DistributionPoint数组作增强for循环,对每一个CRL分发点进行操作,首先DistributionPoint取出DistributionPointName
DistributionPointName是Java中表示CRL分发点名称的类。它用于表示CRLDistPoint扩展字段中的一个完整的CRL分发点。
CRL分发点可以是以下三种类型之一:
名称(Name):这种类型的CRL分发点包含了CRL的发行者的名称,例如"CN=Example Root CA, O=Example Inc., C=US"。
完全限定名(Full Name):这种类型的CRL分发点包含了CRL的URI地址,例如"http://example.com/crl.crl"。
相对名称(Relative Name):这种类型的CRL分发点包含了相对于证书颁发机构的位置的路径,例如"crl/root-ca.crl"。
DistributionPointName类提供了几个方法来获取和设置CRL分发点名称的类型和值。其中最常用的方法是,它返回一个GeneralName对象,可以通过该对象来访问具体的CRL分发点值;然后就是,它返回一个int类型的type,含义是CRL分发点类型。如果CRL分发点类型为"名称"或者"完全限定名",那么GeneralName对象将被转换为GeneralNames对象,从而可以访问其中的所有名称;如果CRL分发点类型为"相对名称",那么GeneralName对象将被转换为RelativeDistinguishedName对象,从而可以访问具体的相对路径。
④那么我们这边只需要取type为完全限定名类型的分发点即可,因为我们的目的是为了获取URI地址,取出对应的完全限定名类型的分发点后,通过getName()并且强转成GeneralNames,然后通过getNames()返回一个由 GeneralName 对象组成的数组,所有通用名称。
⑤最后通过每一个通用名称去进行筛选,把符合条件的取出即是我们最后的CRL地址
我们这边通过2个条件去进行筛选
1.GeneralName.getTagNo()是否为GeneralName.uniformResourceIdentifier
GeneralName.getTagNo() 是 org.bouncycastle.asn1.x509.GeneralName 类中的一个方法,用于获取通用名称类型的标记号。通用名称是 X.509 标准中定义的一种标识实体的方式,例如主体名称、主体替代名称或分发点名称等。
在 ASN.1 编码规范中,每个通用名称类型都有一个唯一的标记号来标识它。getTagNo() 方法返回当前通用名称对象的标记号。
而GeneralName.uniformResourceIdentifier表示 X.509 证书的通用名称类型之一,它表示一个统一资源标识符(URI)。URI 是一种标识某个资源的字符串,它可以指向任何类型的资源,例如 Web 页面、电子邮件地址、文件等。
通常情况下,URI 使用的是 URL(Uniform Resource Locator)或 URN(Uniform Resource Name)格式。
URL 定位到一个资源,并且可以直接访问该资源,而 URN 只是一个命名方式,不包含具体位置信息。
在 X.509证书中,URI 通常被用作 CRL 分发点名称(CRL Distribution Point Name)或颁发者名称(Issuer Name)等标识信息的一部分。
所以我们判断我们的通用名称标记类型是否是URI,不是则直接去找下一个通用名称,是的话接着判断该URI是否是LDAP协议,我们这边只需要http协议的URI,所以不需要LDAP协议的,最终均满足条件的就是最终的CRL URL。
获取CRL的URL代码如下:
完整获取CRI的例子如下:
发现可以获取成功
然后我们可以将CRL URL转化为CRL类
调用其isRevoked()方法判断证书是否吊销,参数接收的是要验证的证书的X509形式类