我正在寻找一种从 X509Certificate2 实例中提取 AuthorityKeyIdentifier 扩展的方法。我没有看到任何对此的内置支持,但由于 Windows 可以正确构建证书链,我知道该功能必须在某种程度上存在。如果答案是滚一个DER解析器,有没有好的实现可以参考?
迭代 X509Certificate2.Extensions 属性中的扩展,并查找 OID 2.5.29.35 的扩展(根据 http://www.alvestrand.no/objectid/2.5.29.35.html)。这就是 AuthorityKeyIdentifier 扩展。
[编辑:添加以下内容。]
Extensions 属性的每个成员都是 ASN 编码的。因此,您可以执行以下操作以获取人类可读或机器可解析的格式:
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
...
X509Extension extension; // The OID 2.5.29.35 extension
AsnEncodedData asndata = new AsnEncodedData(extension.Oid, extension.RawData);
Console.WriteLine(asndata.Format(true));
对于 Microsoft 中间 CA 证书之一,Format() 方法返回以下内容:
[1]Authority Info Access
Access Method=Certification Authority Issuer (1.3.6.1.5.5.7.48.2)
Alternative Name:
URL=http://www.microsoft.com/pki/certs/MicrosoftRootCert.crt
这当然不容易解析,但是你可以查找以正则表达式
\[\d+\]Authority Info Access
开头的行,然后找到其下面带有正则表达式URL=(.+)
的行(八个空格在格式中不清楚)并使用URL在括号内的组中。
对于 2024 年的我来说,使用 AsnEncodedData 的方法不起作用。它返回了一组不可读的字节。 我需要在没有 x509authoritykeyidentifierextension 的 net core 6 上工作。
所以..我必须与 BouncyCastle 一起做出自己的决定。
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Utilities.Encoders;
...
byte[] oid_2_5_29_35_raw = ...;
var mainSequence = DerSequence.GetInstance(oid_2_5_29_35_raw);
var content = DerOctetString.GetInstance(mainSequence[1]);
var contentSequenceBytes = content.GetOctets().ToArray();
var contentSequence = DerSequence.GetInstance(contentSequenceBytes);
// 0 - Index in standart for keyIdentifier
var keyIdentifier = Hex.ToHexString(DerOctetString.GetInstance(contentSequence[0]).GetOctets());
// 2 - Index in standart for authorityCertSerialNumber
var authorityCertSerialNumber = Hex.ToHexString(DerOctetString.GetInstance(contentSequence[2]).GetOctets());
有一个更简单的选项 - 采用一些现有组件,可以在处理证书方面提供更大的灵活性。您可以使用 BouncyCastle 或我们的 SecureBlackbox。