Java 如何获得不可抵赖证书和数字签名证书

Java 如何获得不可抵赖证书和数字签名证书,java,ssl,keystore,pki,Java,Ssl,Keystore,Pki,对于PKI客户端,我需要获得不可否认证书和数字签名证书。我已实施此代码以获取这些证书: keyStore.load(null, null); Enumeration<String> aliases = keyStore.aliases(); while (aliases.hasMoreElements()) { String alias = aliases.nextElement(); if (keyStore.isKeyEntry(alias)) {

对于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.load(null,null);
枚举别名=keyStore.alias();
while(别名.hasMoreElements()){
字符串别名=别名。nextElement();
if(keyStore.isKeyEntry(别名)){
java.security.cert.Certificate=keyStore.getCertificate(别名);
}
}

问题是数字证书和不可否认性证书都有相同的别名。因此,当我调用
keystore.getCertificate
时,系统将始终返回第一个结果,尽管在certmgr.msc窗口中,我可以看到存在两个证书,循环块执行两次,但系统将始终返回第一个证书的重复结果。如何解决此问题?

您不可能有两个别名相同的不同条目。但这就是如何从密钥存储中以列表的形式获取所有一级证书的列表

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);
    }
}
List certificates=new ArrayList();
枚举别名=keyStore.alias();
while(别名.hasMoreElements()){
字符串别名=别名。nextElement();
证书证书=keyStore.getCertificate(别名);
如果(证书!=null){
证书。添加(证书);
}
}

既然您谈论的是
certmgr.msc
并使用
keyStore.load(null,null)
,我猜想您使用的是来自的
WINDOWS-ROOT
WINDOWS-MY
密钥库

不幸的是,存在一个错误,因为它可以对多个条目重复使用同一别名,从而使访问某些证书变得困难或不可能

该密钥库使用的别名实际上是证书的“友好名称”(用MS-CAPI术语)。虽然友好名称在Windows证书存储中不需要是唯一的,但别名需要是唯一的

大概是因为您似乎在谈论针对同一实体但用途不同的两个不同证书,所以默认情况下它们可能使用相同的友好名称

解决此问题的一种方法是在Windows应用商店中识别具有不同友好名称的证书:在
certmgr.msc
中,选择证书,右键单击,选择“属性”,然后更改其“友好名称”


如果您有两个具有唯一友好名称的不同证书(出于不同的密钥使用或任何其他原因),那么它们应该在密钥库中以不同的别名显示。

我不是在问如何区分不可否认性和数字签名的问题。我想问的是提取证书的过程,所以请您建议一种加载两个证书的方法,因为我现在这样做,检测两个证书,但每次迭代都加载相同的对象。我更新了答案,所以现在列表将包含密钥存储区拥有的所有证书。这是正确的想法,但不幸的是,由于Windows应用商店中的一个实现细节(bug?),这不会列出应用商店中的所有证书。。。