How to support multiple truststores in Java SSL client applications

In our Java application, we need to use HTTPS protocol to communicate with the server list on SSL The list of servers to communicate will change at run time At first we didn't have any server certificates At run time, we will obtain the certificate of the new server and add the public key certificate to the truststore; Any new HTTPS connection to the server should use the updated trust store

We think we should use two truststores, one cacerts (the default one is attached to JRE) and other certificates containing servers we dynamically add / remove from the list This will ensure that we do not modify Java's default truststore (cacerts)

Please suggest how to achieve this goal In addition, is there any way to use a specific trust store only for specific threads in Java, so that other (existing and new) threads should still use the default Java truststore (cacerts), and a specific thread will use a specific trust store server

Thank you, Deepak

Solution

If you are importing certificates dynamically, you may need to use a custom x509trustmanager This is done when configuring sslcontext, which itself is used to create sslsocketfactory or ssengine

JSS lutils is a library that lets you wrap an existing trust manager and customize certain settings You don't need it, but it may help

This will follow these guidelines:

PKIXSSLContextFactory sslContextFactory = new PKIXSSLContextFactory();
sslContextFactory.setTrustManagerWrapper(new x509trustmanagerWrapper() {
    @Override
    public x509trustmanager wrapTrustManager(final x509trustmanager origManager) {
        return new x509trustmanager() { 
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return origManager.getAcceptedIssuers();
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain,String authType)
                    throws CertificateException {
                try {
                    // This will call the default trust manager
                    // which will throw an exception if it doesn't kNow the certificate
                    origManager.checkServerTrusted(chain,authType);
                } catch (CertificateException e) {
                    // If it throws an exception,check what this exception is
                    // the server certificate is in chain[0],you Could
                    // implement a callback to the user to accept/refuse
                }
            }

            @Override
            public void checkClientTrusted(X509Certificate[] chain,String authType)
                    throws CertificateException {
                origManager.checkClientTrusted(chain,authType);
            }
        };
    }
});
SSLContext sslContext = sslContextFactory.buildSSLContext();

((PKIX) sslcontextfactory and x509trustmanagerwrapper are from jsslutils, but the rest are from J2SE / J2EE.)

You may want to catch some certificateexceptions (see subclasses) If you callback the user, the SSL / TLS connection may fail due to the timeout of SSL / TLS handshake (if the callback time is too long to reply)

You can then use sslcontext Setsslcontext (...) (from Java 6) uses this sslcontext as the default, but this is not necessarily a good idea If you can, please pass sslcontext to the library for SSL / TLS connection How to do this varies, but Apache HTTP client 4 X has several options to configure its SSL settings, one by passing keystores and the other by passing sslcontext

By checking the current thread in x509 trust manager, you can also use each thread instead of each object to connect (Library dependent): this may complicate things in synchronization and thread management / perception

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>