我正在尝试解密 S/MIME 电子邮件(最初通过 Outlook 发送),为此,我使用了 bouncycastle API。不过,我遇到了障碍。
在 Windows 证书存储中,我有收件人的证书。我之前曾使用它向对方发送签名和加密的电子邮件,而对方又使用它向我发送加密回复。然后,我将证书(带有私钥)导出为 .pfx 文件,并将此 pfx 文件加载到 Java KeyStore 中。但是,它不起作用,我怀疑这是因为主题密钥标识符不匹配。
这是我用来从 KeyStore 获取主题密钥 ID 的代码:
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));
}
}
这将打印出以下密钥标识符:
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 证书存储时,密钥标识符是不同的:
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 个字节,对吗?)。
更令人困惑的是,当我使用 bouncycastle API 解析 S/MIME 电子邮件并通过收件人 ( SMIMEEnveloped.getRecipientInfos().getRecipients()
) 时,返回的唯一收件人(应该只有一个)具有以下主题密钥标识符:
04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3
...它只有两个额外的字节,而不是四个,我认为这就是我无法使用证书解密电子邮件的原因。
为什么这些主题密钥标识符都不匹配?我究竟做错了什么?