How to support multiple TrustStores in a Java Java client application

In our Java application, we need to contact the list of servers using SSL using the https protocol. The list of servers for communication will change at runtime. Initially, we do not have a server certificate. At run time, we will receive a new server certificate and add the public key certificate to the trust store; and any new https connection to the server should use the updated trust store.

We think that we should use two trust stores, one cacerts (by default, one is sent with jre) and the other containing server certificates, which we add / remove dynamically in the list. This ensures that we will not modify the standard TrustStore (cacerts) java.

Please suggest how this can be achieved. Also, is there any way to use a specific trust store only for a specific thread in java, so that other (existing and new) threads should still use the default java trueststore (cacerts), and one particular thread will use a specific trusted network for server.

Thanks Deepak

+7
java certificate ssl truststore
source share
2 answers

If you want to dynamically import a certificate, you may need to use x509TrustManager . This is done when configuring SSLContext , which itself is used to create an SSLSocketFactory or SSLEngine .

jSSLutils is a library that allows you to wrap existing trust managers and configure specific parameters. You do not need it, but it can help.

This will go along these lines:

 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 come from jSSLutils, but the rest are available with J2SE / J2EE.)

There are several CertificateException s that you might want to catch (see subclasses). If you are making a callback for the user, it is possible that the SSL / TLS connection will not be completed the first time due to a timeout in the SSL / TLS handshake (if the callback takes too long to get a response.)

Then you can use this SSLContext as your default using SSLContext.setSSLContext(...) (from Java 6), but this is not necessarily a good idea. If you can, pass SSLContext to the library that makes the SSL / TLS connection. How this is done changes, but Apache HTTP Client 4.x, for example, has several options for setting its SSL settings, one of which is KeyStore s transfer, the other is SSLContext transfer.

You can also use something in the stream instead of a single object that will connect (depending on the library) by checking the current stream in x509TrustManager : this would probably make things a little more complicated in terms of synchronization and flow control / awareness trustee.

+5
source share

This question is so old that I have doubts, my bit will help anyone, but here it goes ...

If you want to solve the OP problem (source poster) without resorting to code changes, you can configure the JVM (I tested only with Tomcat) to support the desired OP configuration: 1. Leave only the “packaged” JDK cacerts file 2. import your certificates into separate file and trust them your JAVA applications.

I simply imported my additional certificate into a separate file and then with great success referred to its launch in the JVM with the parameter '-Djavax.net.ssl.trustStore = $ JAVA_HOME / jre / lib / security / jssecacerts' but I think that recent ( several) JAVA security issues have changed the automatic inclusion of the cacerts file distributed with the SDK.

So, I found a great solution using intel from this post and these pages (with some minor changes): - http://www.coderanch.com/t/529157/Tomcat/Configure-Tomcat-trust-store-cacerts - http : //andyarismendi.blogspot.com/2012/01/changing-tomcats-ca-trust-keystore-file.html

What I did before: - set the trustStore JVM parameter to a separate keystore file (so that I import additional certificates) as follows

What am I doing now: - Set the trustStore parameter to a "packed" cacerts file - Set the keyStore parameter to my additional certificate file - Set the keyStorePassword parameter to my keyStore password (default is changeit)

What it looks like:

 -Djavax.net.ssl.trustStore=$JAVA_HOME/jre/lib/security/cacerts \ -Djavax.net.ssl.keyStore=$JAVA_HOME/jre/lib/security/jssecacerts \ -Djavax.net.ssl.keyStorePassword="changeit" \ 

Hope this helps someone. I am not 100% sure that you need to specify the keyStore password since you are not using trustStore, but it works when you do it.

+2
source share

All Articles