为什么我的键标识符不匹配? [英] Why doesn't my key identifier match?

查看:175
本文介绍了为什么我的键标识符不匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解密S / MIME电子邮件(最初通过Outlook发送),为此,我使用bouncycastle API。

I'm attempting to decrypt an S/MIME email (sent originally via Outlook), and to do that, I'm using the bouncycastle API. I'm running into a snag, though.

在Windows证书存储中,我拥有收件人的证书。我以前使用它发送一个签名和加密的电子邮件到对方,他们反过来使用它给我一个加密的答复。然后,我将证书(使用私钥)导出为.pfx文件,并将此pfx文件加载到Java KeyStore中。然而,它不工作,我怀疑这是因为主题键标识符不匹配。

I have, in the Windows certificate store, the certificate for the recipient. I had previously used it to send a signed and encrypted email to the other party, and they in turn used it to send me an encrypted reply. I then exported the certificate (with private key) as a .pfx file, and I loaded this pfx file into a Java KeyStore. It doesn't work, however, and I suspect that's because the subject key identifiers don't match.

这是我使用的代码,以获取主题键ID从KeyStore:

Here's the code I'm using to get the subject key id from the KeyStore:

KeyStore ks = KeyStore.getInstance("PKCS12");
char[]   pw = "password".toCharArray();

ks.load(new FileInputStream("d:\\cert_priv_key.pfx"), pw);

Enumeration en = ks.aliases();

while( en.hasMoreElements() )
{
    String alias = (String)en.nextElement();
    System.out.println(alias);

    if( ks.isKeyEntry(alias) )
    {
        Certificate[]   chain = ks.getCertificateChain(alias);
        X509Certificate cert  = (X509Certificate)chain[0];

        byte[] id = cert.getExtensionValue("2.5.29.14");

        System.out.println("  " + toHex(id));
    }
}

这将输出以下键标识符:

This prints out the following key identifier:

04 16 04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

但是,当我检查Windows证书存储区时,密钥标识符是不同的:

When I check the Windows certificate store, however, the key identifier is different:

88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

KeyStore在前面返回一个额外的4个字节(主键标识符应该是密钥的160位SHA1散列,因此长度为20个字节,正确吗?

The KeyStore returns an extra 4 bytes in the front (the subject key identifier should be the 160-bit SHA1 hash of the key, and therefore 20 bytes long, correct?).

更令人困惑的是,当我使用bouncycastle API解析S / MIME电子邮件,并通过收件人( SMIMEEnveloped.getRecipientInfos ().getRecipients()),返回的唯一收件人(应该只有一个)具有此主题标识符:

Even more confusing is the fact that when I parse the S/MIME email using the bouncycastle API, and go through the recipients (SMIMEEnveloped.getRecipientInfos().getRecipients()), the only recipient returned (there should be only one) has this subject key identifier:

04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

...它只有两个额外的字节,而不是四个,我认为这是为什么我无法解密带有证书的电子邮件。

... it has only two extra bytes, not four, and I assume this is why I'm unable to decrypt the email with the certificate.

为什么这些主旨标识符没有匹配?我做错了什么?

Why do none of these subject key identifiers match up? What am I doing wrong?

推荐答案

如果你理解所有的规范,所有这些答案是一致的,混乱如果你不。第一个要查看的是 RFC 5280,第4.2.1.2节。在这种情况下,使用方法(1)。接下来,查看KeyIdentifier定义中的 A.2 部分。它定义为OCTET STRING。现在看看如何对ASN.1 OCTET STRING进行编码。它应该以十六进制04开始,后跟字节长度(20字节,或14 hex),后跟实际的八位字节串(SHA1哈希)。因此,扩展的内容应为

All these answers are consistent if you understand all the specs, but of course that means they are confusing if you don't. The first place to look is in RFC 5280, section 4.2.1.2. In this case method (1) is used. Next, look at section A.2 at the definition of KeyIdentifier. It is defined as an OCTET STRING. Now look at how an ASN.1 OCTET STRING should be encoded. It should start out with hex 04 followed by the length in bytes (20 bytes, or 14 hex) followed by the actual octet string (the SHA1 hash). So the contents of the extension should be

04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

最后,看看扩展。它说,扩展值必须编码为OCTET STRING。在此特定扩展的情况下,净效果是在一行中作为OCTET STRING进行两次编码。在此级别,OCTET STRING是以前的OCTET STRING,其中包含两个头字节 04 14 ,因此长度为十六进制16,编码为

Finally, look at the ASN.1 definition of Extension. It says that the extension value must be encoded as an OCTET STRING. In the case of this particular extension, the net effect is that is get encoded twice in a row as an OCTET STRING. At this level the OCTET STRING is the previous OCTET STRING which includes the two header bytes 04 14, so the length is hex 16, and the encoding is

04 16 04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

这是 X509Extension.getExtensionValue()方法。现在,键ID的有趣部分只是以 88 开头的SHA1哈希,因此这是Windows实用程序显示的内容。显然,你使用的bouncycastle方法显示的扩展名,而不做额外的解码。

This is the value returned by the X509Extension.getExtensionValue() method. Now the interesting part of the key id is just the SHA1 hash which start with 88, so this is what the Windows utility displays. Obviously the bouncycastle method you are using displays the extension without doing additional decoding.

这篇关于为什么我的键标识符不匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆