如何为PKI客户端获取非拒绝和数字签名证书
问题描述:
我需要获得不可否认和数字签名证书。我已经实现了这个代码来获得这些证书:如何为PKI客户端获取非拒绝和数字签名证书
keyStore.load(null, null);
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
if (keyStore.isKeyEntry(alias)) {
java.security.cert.Certificate certificate = keyStore.getCertificate(alias);
}
}
问题是,数字和不可抵赖性证书具有相同的别名。所以当我打电话给keystore.getCertificate
时,系统总是会返回第一个结果,尽管在certmgr.msc窗口中我可以看到有两个证书存在,而LOOP块执行两次,但系统总是会从第一个证书返回重复结果。我如何解决这个问题?
答
您不能真正拥有两个具有相同别名的不同条目。但是,这是如何从密钥库获得所有第一级证书的列表,列表
List<Certificate> certificates = new ArrayList<Certificate>();
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
Certificate certificate = keyStore.getCertificate(alias);
if (certificate != null) {
certificates.add(certificate);
}
}
答
既然你在谈论certmgr.msc
和使用keyStore.load(null, null)
,我相信你正在使用的WINDOWS-ROOT
或WINDOWS-MY
密钥库,来自SunMSCAPI provider。
不幸的是,有一个issue with this provider,因为它可以重复使用多个条目相同的别名,从而使访问某些证书很困难或不可能。
此密钥库使用的别名实际上是证书的“友好名称”(在MS-CAPI术语中)。尽管Windows证书存储区中的友好名称不必是唯一的,但别名的名称必须是。
大概是因为你似乎在谈论同一实体的两个不同的证书,但具有不同的目的,他们很可能默认使用相同的友好名称。
解决此问题的一种方法是在Windows应用商店中用不同的友好名称标识您的证书:在certmgr.msc
中,选择证书,右键单击,选择“属性”并更改其“友好名称”。
如果您有两个具有唯一友好名称的不同证书(用于不同的密钥用途或任何其他原因),那么它们应该在您的KeyStore中显示不同的别名。
我绝对不会问如何区分不可否认性和数字签名的问题。我问的是提取证书的过程,因此,请您提出一种加载两个证书的方法,因为我现在正在执行的方式会检测两个证书,但在每次迭代中加载相同的对象 – user435245
已经更新了我的答案,所以现在列表将包含密钥存储所拥有的所有证书。 – divanov
这是正确的想法,但不幸的是,由于Windows存储中的实现细节(bug?),这不会列出商店中的所有证书...... – Bruno