如何以编程方式检查 X509 证书是否已在 Java Trust Store 中? [英] How to check if X509 certificate is already in the Java Trust Store programatically?

查看:33
本文介绍了如何以编程方式检查 X509 证书是否已在 Java Trust Store 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个客户端 GUI,它接受自签名服务器证书并将它们添加到信任库,就像任何浏览器一样.问题是我的客户端应用程序每次启动时都要求提供证书,换句话说,它不记得证书已经在信任库中了.我该如何实施?这就是我编写信任存储文件的方式:

I am developing a client GUI that accepts self signed server certificates and adds them to the trust store just like any browser would do. The problem is that my client application asks for the certificate every time it is started, in other words it does not remember that the certificate is already in the trust store. How do I implement this? This is how I am writing my trust store files:

 public void WriteTrustStore(String alias, X509Certificate c){
    char[] password = "changeit".toCharArray();
    char SEP = File.separatorChar;
    keystoreFile = new File(System.getProperty("java.home")
            + SEP + "lib" + SEP + "security" + SEP + "cacerts");
    try {
        setTrustStore(trustStore);
        FileInputStream in = new FileInputStream(keystoreFile);
        trustStore.load(in, password);
        in.close();
        trustStore.setCertificateEntry(alias, c);
        FileOutputStream out = new FileOutputStream(keystoreFile);
        trustStore.store(out, password);
        out.close();
    } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
        e.printStackTrace();
    }
}

然后我有另一种方法来初始化我的 SSL 上下文并通过执行以下操作来创建动态别名:

Then I have another method where I am initializing my SSL Context and also creating dynamic alias names by doing something like:

string alias = getHostname() + "-" + getPortname();

最后我有一个别名:

"myhost-5001"

然后我调用 WriteTrustStore(alias,certificate) 方法.

And then I call the WriteTrustStore(alias,certificate) method.

但是在程序的下一次执行运行中,如果我尝试使用此别名查找证书,我总是最终得到空指针异常.

But in the next execution run of the program if I try to find the certificate with this alias name, I always end up getting a Null Pointer Exception.

我知道信任库文件具有如下属性:

I know that a truststore file has a property like:

trustStore.containsAlias(alias)

我试过了,

if(trustStore.containsAlias(alias) == false){
     WriteTrustStore(alias, (X509Certificate) cert)
     }
     else {
           System.out.Println("Certificate already in trust store!");
     }

但我仍然收到空指针异常.而且我知道别名为 myhost-5001 的证书在 Java 信任库中,我使用 keytool 和 portecle 进行了交叉检查.

But still I get a Null-Pointer exception. And also I know that the certificate with alias name myhost-5001 is in the Java trust store, I crossed checked using keytool and portecle.

感谢您的帮助!

推荐答案

我想通了,有两种方法可以做到.

I figured it out, there are two ways this can be done.

第一种方法

我在这里找到了这个:检查可信证书,您可以在其中枚举别名像这样:

I found this here: Check for trusted certificates, where you enumerate over aliases like this:

Enumeration en = keystore.aliases();
String ALIAS = "" ;

X509Certificate signingcert = null;

while (en.hasMoreElements())
{
    X509Certificate storecert = null;
    String ali = (String)en.nextElement() ;
    if(keystore.isCertificateEntry(ali))
     {
        storecert = (X509Certificate)keystore.getCertificate(ali);
        if( (storecert.getIssuerDN().getName()).equals(issuerdn))
        {
         try{
            System.out.println("Found matching issuer DN cert in keystore:\r\nChecking signature on cert ...") ;
            cert.verify(storecert.getPublicKey()) ;
            System.out.println("Signature verified on certificate") ;
            signingcert = storecert;
            break;
          }
         catch(Exception exc){
            System.out.println("Failed to verify signature on certificate with matching cert DN");
          }             
        }           
    }
    else
     if(keystore.isKeyEntry(ali))
        System.out.println(ali + "   **** key entry ****");
}

第二种方法

只需创建一个重复的证书,在信任库中查找具有您传递的别名的证书.

Just create a duplicate certificate that looks in the trust store for a certificate with the alias name you are passing.

X509Certificate DuplicateCert = (X509Certificate) trustStore.getCertificate(alias);

第一种方法更安全,因为您也在查看颁发者 DN,但需要更长的时间,第二种方法更简单且更短.

First method is safer because you are also looking at the Issuer DN but takes longer, second method is simple and shorter.

第二种方法对我来说很有吸引力,你可以在这里找到完整的 GUI 代码审查,看看我是如何使用它的:JAX-WS 客户端 SSL 代码审查

Second method works like a charm for me, you can find the complete GUI code review here and see how I am using it: JAX-WS client SSL code review

这篇关于如何以编程方式检查 X509 证书是否已在 Java Trust Store 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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