Cob*_*ink 6 java certificate subject decoding x509
在我的例子中有三个证书,假设它们形成一个链但我不知道它们中哪个签署了哪个:
X509Certificate c1 = ....
X509Certificate c2 = ....
X509Certificate c2 = ....
Run Code Online (Sandbox Code Playgroud)
我想知道哪个证书负责签署另一个证书.
计划是获取" AuthorityKeyIdentifier "并将其与" SubjectKeyIdentifier " 匹配.
import org.bouncycastle.asn1. DEROctetString;
private static String decodeKey(byte[] e) {
DEROctetString octet = new DEROctetString(e);
return octet.toString();
}
String subjectKeyId = decodeKey(c.getExtensionValue("2.5.29.14"));
String authorityKeyId = decodeKey(c.getExtensionValue("2.5.29.35"));
Run Code Online (Sandbox Code Playgroud)
我得到以下证书(按照链的顺序):主题/权限密钥ID对
解码后SubjectKeyIdentifier和AuthorityKeyIdentifier的值:
证书1 :(链的末尾)
#0416041482b7384a93aa9b10ef80bbd954e2f10ffb809cde
#04183016801482b7384a93aa9b10ef80bbd954e2f10ffb809cde
Run Code Online (Sandbox Code Playgroud)
证书2:由证书1签署
#04160414ab8059c365836d1d7d13bd19c3ec1a8f0d476aa3
#04183016801482b7384a93aa9b10ef80bbd954e2f10ffb809cde
Run Code Online (Sandbox Code Playgroud)
证书3:由证书2签署
(no SubjectKeyIdentifier - null bytes)
#041830168014ab8059c365836d1d7d13bd19c3ec1a8f0d476aa3
Run Code Online (Sandbox Code Playgroud)
格式化和对齐以便于阅读(与顶部相同)
------------------------------------------------------------------------------
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
------------------------------------------------------------------------------
Certificate 1
#04 16 04 14 82 b7 38 4a 93 aa 9b 10 ef 80 bb d9 54 e2 f1 0f fb 80 9c de
#04 18 30 16 80 14 82 b7 38 4a 93 aa 9b 10 ef 80 bb d9 54 e2 f1 0f fb 80 9c de
Certificate 2
#04 16 04 14 ab 80 59 c3 65 83 6d 1d 7d 13 bd 19 c3 ec 1a 8f 0d 47 6a a3
#04 18 30 16 80 14 82 b7 38 4a 93 aa 9b 10 ef 80 bb d9 54 e2 f1 0f fb 80 9c de
Certificate 3
=== == == == == == == == == == == NO DATA == == == == == == == == == == == ==
#04 18 30 16 80 14 ab 80 59 c3 65 83 6d 1d 7d 13 bd 19 c3 ec 1a 8f 0d 47 6a a3
Run Code Online (Sandbox Code Playgroud)
我期待c3的AuthorityKeyIdentifier等同于c2的SubjectKeyIdentifier.这似乎不是这种情况.
编辑:结果的某些部分似乎匹配,我对"SubjectKeyIdentifier"有一些想法 - 它始终以'#04'开头,后跟内容的长度(十六进制).我现在对如何解码"SubjectKeyIdentifier"有一定的了解,但"AuthorityKeyIdentifier"对我来说仍然是一个很大的谜.
相关的SO帖子
我在解码时做错了吗?为什么AuthorityKeyIdentifier与签名证书的SubjectKeyIdentifier没有正确匹配?
如果您查看 RFC5280 中 SKI 和 AKI 的 ASN.1 定义(按照您问题中的链接),差异就会变得明显:
SubjectKeyIdentifier ::= KeyIdentifier
AuthorityKeyIdentifier ::= SEQUENCE {
keyIdentifier [0] KeyIdentifier OPTIONAL,
authorityCertIssuer [1] GeneralNames OPTIONAL,
authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
KeyIdentifier ::= OCTET STRING
Run Code Online (Sandbox Code Playgroud)
因此,AKI 不是 OCTET STRING,而是三个可选元素的 SEQUENCE。这些元素之一是可以与 SKI 进行比较的八位字节字符串。
的分辨编码规则(DER)确定这些ASN.1结构的字节表示。AKI 扩展的各个字节具有以下含义(请参阅ASN.1、BER 和 DER 子集的外行指南):
04 18 30 16 80 14 82 b7 38 4a 93 aa 9b 10 ef 80 bb d9 54 e2 f1 0f fb 80 9c de
04 OCTET STRING
18 LENGTH
30 SEQUENCE
16 LENGTH
80 CONTEXT-SPECIFIC PRIMITIVE TAG 0
14 LENGTH
.. DATA
Run Code Online (Sandbox Code Playgroud)
前两个字节 (04 18) 是扩展结构的一部分(如相关问题中解释的为什么我的密钥标识符不匹配?),实际的 AKI 扩展内容从“30 16”开始。
用于解码 AKI 的 Java 代码应如下所示(使用 Bouncy Castle):
byte[] extensionValue = cert.getExtensionValue("2.5.29.35");
byte[] octets = DEROctetString.getInstance(extensionValue).getOctets();
AuthorityKeyIdentifier authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(octets);
byte[] keyIdentifier = authorityKeyIdentifier.getKeyIdentifier();
String keyIdentifierHex = new String(Hex.encode(keyIdentifier));
Run Code Online (Sandbox Code Playgroud)
对于解码 SKI:
extensionValue = cert.getExtensionValue("2.5.29.14");
octets = DEROctetString.getInstance(extensionValue).getOctets();
SubjectKeyIdentifier subjectKeyIdentifier = SubjectKeyIdentifier.getInstance(octets);
keyIdentifier = subjectKeyIdentifier.getKeyIdentifier();
keyIdentifierHex = new String(Hex.encode(keyIdentifier));
Run Code Online (Sandbox Code Playgroud)
此外,这两个扩展都是可选的。如果您的代码应该使用任意证书,则需要回退机制(例如验证签名)。
归档时间: |
|
查看次数: |
1443 次 |
最近记录: |