我正在使用: java.security.cert.X509Certificate 包。和 java.security.cert.X509CRL;
当我获得扩展值时,例如当OID = 2.5.29.14时(它是SubjectKeyIdentifier) 的 cert.getExtensionValue( “2.5.29.14”); 我得到这个字节[]范围:
[4,22,4,20,的 5125,-118,106,-44,108,39,-74,-108,-20,-27,-32,-113,64,-69,125,-8,102 ,-52,-24
当我在证书中看到时,SubjectKeyIdentifier 从5开始。
问题1:这个范围的开头是什么?它是4个字节。
当我在X509CRL中看到AuthorityKeyIdentifier时(如果CRL由此证书签名,则CRL的AuthorityKeyIdentifier == SubjectKeyIdentifier Of证书)也有相同的内容:
[4,24,48,22,-128,20,的 5125,-118,106,-44,108,39,-74,-108,-20,-27,-32,-113,64, -69,125,-8,102,-52,-24 ] 但是开头还有另外6个字节。
问题2:这个范围的开头是什么?它是6个字节。
和另一个问题:
问题3:如何解析ExtensionValue以便只获取Identifier值。这4和6字节是固定的吗?什么是解析的最佳方法?
答案 0 :(得分:4)
回答问题1 : 这些字节是 ASN 1 数据结构的二进制表示。 ASN 1(摘要Syntaxt Notation One)是由 ITU 定义的标准,通常用于RFC /消息协议中,用于定义更高级别的数据结构(例如X.509证书)。
ASN 1具有由tripels(标签类型,长度,值)组成的基本语法。一些ASN 1标签允许嵌套元素。在你的情况下,你有一个
ASN 1 OCTET STRING (tag type 4) with a length of 22 which contains an ASN 1 OCTET STRING (the second 4 in the byte array) of length 20. The key identifier
回答问题2 :AuthorityKeyIdentifier的定义与SubjectKeyIdentifier不同(有关详细信息,请参阅RFC 5280)。在你的情况下它是
ASN 1 OCTET STRING of length 24 which contains an ASN 1 CONSTRUCTED SEQUENCE (tag type 16 for ASN 1 SEQUENCE and tag type 32 for ASN 1 CONSTRUCTED logically or'red -> 16 + 32 = 48) of length 22 which contains ASN 1 CONTEXT SPECIFIC DATA (tag type 128 which results in -128 cast to a byte) of length 20 The key identifier
数据结构与SubjectKeyIdentifier扩展名的不同之处在于,AuthorityKeyIdentifier扩展名可能包含用于验证当前证书的证书的颁发者和序列号。
在您的情况下,两个密钥标识符(字节数组的最后20个字节)是相等的。因此,您可以使用第一个问题中提到的证书来验证第二个问题中提到的CRL的签名(验证可以防止受操纵的CRL)。
回答问题3 :我强烈建议您不要自己实施ASN 1。使用像Bouncycastle这样的图书馆。要正确解析数据结构,必须使用适当的类,特别是对于Bouncycastle,没有便利类可以通过尽力而为的方法来确定ASN 1结构的类型。然而,这种方法几乎不可能实施。
例如,让我们说我们有字节数组[4,4,67,68,45,53] 此数据(ASN 1 OCTET STRING)是否代表:
由于在ASN 1上定义的协议数量庞大,因此不能说数据应该代表哪个对象。此外,假设所有列出的解释都是可能的(它们不是)哪一个应该由通用库选择?再次假设此数据将是有效的JPEG图像和有效的LDAP消息。 JPEG会有透明度,rgb颜色等等。 LDAP消息具有协议操作的ID(BIND请求,BIND响应,SEARCH请求......)以及更多内容。你想做一些棘手的操作来从一个转换成另一个吗?
此外,数据可能应该代表与我们奇妙的图书馆猜测完全不同的东西。不幸的是,由于TCP软件包损坏,数据被破坏了.......现在我们的图书馆无法向我们提供类似于
的消息"Bad LDAP message, syntax violated by ..."
因为它意外地将数据解析为完全合法的JPEG。
要解析显示的数据,例如使用Bouncycastle(假设版本为1.51):
//retrieve the certificate from somewhere
X509Certificate c = ...;
String oid = Extension.authorityKeyIdentifier.getId();
byte[] extensionValue = c.getExtensionValue(oid);
ASN1OctetString akiOc = ASN1OctetString.getInstance(extensionValue);
AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(akiOc.getOctets());
然后你可以调用
aki.getKeyIdentifier();
aki.getAuthorityCertIssuer();
aki.getAuthorityCertSerialNumber();
进一步处理。
答案 1 :(得分:0)
cert.getExtensionValue(“2.5.29.14”)的返回是OCTET STRING的编码。
在Bouncy Castle中,您可以获得实际的编码值:
byte[] octets = ASN1OctetString.getInstance(cert.getExtensionValue("2.5.29.14")).getOctets();
对于SubjectKeyIdentifier,此值将是另一个编码的OCTET STRING,因此您可以重复该过程(如使用ASN1OctetString)或使用SubjectKeyIdentifier.getInstance(八位字节)。对于AuthorityKeyIdentifier,可以遵循相同的过程。
如果您正在做很多这类事情,您可能还想查看bcpkix发行版中org.bouncycastle.cert中的类。持有者类的设计使得这种分析和处理更容易。