从证书中检索完整的扩展值

时间:2013-04-24 16:23:57

标签: java certificate ssl-certificate x509certificate bouncycastle

我正在使用: 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字节是固定的吗?什么是解析的最佳方法?

2 个答案:

答案 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)是否代表:

  • LDAP消息或
  • JPEG或
  • 人类可读的字符串或
  • ...?

由于在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中的类。持有者类的设计使得这种分析和处理更容易。