- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试解密 S/MIME 电子邮件(最初通过 Outlook 发送),为此,我使用了 bouncycaSTLe API。不过,我遇到了麻烦。
我在 Windows 证书存储中有收件人的证书。我之前用它给对方发送了一封签名加密的邮件,对方又用它给我发了一封加密的回复。然后,我将证书(带有私钥)导出为 .pfx 文件,并将此 pfx 文件加载到 Java KeyStore 中。但是,它不起作用,我怀疑这是因为主题 key 标识符不匹配。
这是我用来从 KeyStore 获取主题 key 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));
}
}
这会打印出以下 key 标识符:
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 证书存储时, key 标识符不同:
88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3
KeyStore 在前面返回额外的 4 个字节(主题 key 标识符应该是 key 的 160 位 SHA1 哈希值,因此长 20 个字节,对吗?)。
更令人困惑的是,当我使用 bouncycaSTLe API 解析 S/MIME 电子邮件并检查收件人 (SMIMEEnveloped.getRecipientInfos().getRecipients()
) 时,唯一的收件人返回(应该只有一个)具有此主题 key 标识符:
04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3
...它只有两个额外的字节,而不是四个,我想这就是我无法用证书解密电子邮件的原因。
为什么这些主题键标识符都不匹配?我做错了什么?
最佳答案
如果您了解所有规范,所有这些答案都是一致的,但当然,如果您不了解,这意味着它们会令人困惑。首先要看的地方是RFC 5280, section 4.2.1.2 .在这种情况下,使用方法 (1)。接下来看section A.2在 KeyIdentifier 的定义处。它被定义为 OCTET STRING。现在看看一个 ASN.1 OCTET STRING should be encoded 是如何产生的.它应该以十六进制 04 开头,后跟以字节为单位的长度(20 个字节,或 14 个十六进制),然后是实际的八位字节字符串(SHA1 哈希)。所以扩展的内容应该是
04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3
最后看一下Extension的ASN.1定义.它表示扩展值必须编码为 OCTET STRING。在这个特定扩展的情况下,最终效果是连续两次编码为 OCTET STRING。在这一层 OCTET STRING 是前一个 OCTET STRING,它包括两个头字节 04 14
,所以长度是十六进制 16,编码是
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() 返回的值方法。现在, key ID 中有趣的部分只是以 88
开头的 SHA1 哈希,因此这就是 Windows 实用程序显示的内容。显然,您使用的 bouncycaSTLe 方法显示了扩展名而没有进行额外的解码。
关于java - 为什么我的 key 标识符不匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6523081/
C++ Primer 说: The identifier we define in our programs may not contain 2 consecutive underscores, no
标识符术语在文档 alongside constants 中定义。 , 使用几乎相同的用例,尽管术语在运行时计算它们的值,而常量在编译时得到它。潜在地,这可能会使术语使用全局变量,但这是一个遥远而丑陋
我想知道,.Net 标识符中接受哪些字符? 不是 C# 或 VB.Net,而是 CLR。 我问这个的原因是我正在查看 yield return 语句是如何实现的 (C# In Depth),并看到
在PowerShell中,当我专门使用Active Directory时,通常会编译一个包含一组人群列表的对象,通常使用$x = get-adgroup -filter {name -like "*"
使用 hibernate 时: 我必须为每个实体指定一个 ID 或复合 ID,如果我想使用没有任何主键且没有复合键的表怎么办... 提前致谢 最佳答案 没有键的表不是一个好的关系模型。我不会推荐它。
所以我有一些代码正在尝试编译,但我不断收到此错误: 3SATSolver.java:3: expected 这是代码。我只是没有看到什么吗? import java.util.ArrayList;
我正在寻找有关 C 标准(C99 和/或 C11)部分内容的一些说明,主要是关于标识符的使用。 上下文是一个完整的C99标准库的实现,我希望它完全符合标准。 基本问题是:C 标准允许我在多大程度上声明
我有这个 Shader.h 文件,我正在用这段代码制作它: #include #include #include #include in vec2 TexCoords; out vec4 co
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
这是我的代码: #include "stdafx.h" #include #include #include #include using namespace std; int _tmain(
pthread_create() 的第一个参数是一个thread 对象,用于标识新创建的线程。但是,我不确定我是否完全理解其中的含义。 例如,我正在编写一个简单的聊天服务器并且我计划使用线程。线程会随
我想从我的标识符中获得匹配项。 我在 {/describe:foo} 中有一个这样的字符串,我正在尝试匹配 {/describe:} 以返回 foo,但我没有得到正确的正则表达式,会有人介意指出我做错
我遇到了一个奇怪的问题,我似乎找不到答案,但我想我不妨问问。 我有一个执行碰撞检查的抽象类,它有一个“更新”函数,以及“updateX”和“updateY”函数。 class MapCollidabl
我正在尝试创建一个程序来将所有文件从一个目录复制到另一个目录。但我遇到了一个基本问题。它说当我尝试在第 52 行编译时需要标识符。 public bool RecursiveCopy() {
1>cb.c(51): error C2061: syntax error : identifier 'SaveConfiguration' 1>cb.c(51): error C2059: synt
我刚刚发现命名变量 arguments 是个坏主意。 var arguments = 5; (function () { console.log(arguments); })(); Outpu
我们对我们的网站进行了安全测试,并发现了一个漏洞。 问题 If the session identifier were known by an attacker who had access to t
为了估计程序在一次内核启动中可以处理多少数据,我尝试使用 cudaMemGetInfo() 获取一些内存信息。但是,编译器告诉我: 错误:标识符“cudaMemGetInfo”未定义 cudaGetD
我发现我需要使用 xpath 查询来定位几乎是 regexp 类型的字符串,但无法看到如何管理它。我正在使用的当前查询是: $result = $xpath->query('//ul/li[sta
我正在创建我的学生计划表的虚拟版本,它基本上可以让你记下你有哪些科目的作业。 这是界面: 用户从组合框中选择主题,并在相邻的备忘录中输入一些注释。完成后,他们将单击“保存”按钮,将其保存到 .ini
我是一名优秀的程序员,十分优秀!