Registering multiple keystores in JVM

Viewed 78790

I have two applications running in the same java virtual machine, and both use different keystores and truststores.

A viable option would be use a single keystore and import all the other ones into the shared keystore (e.g. keytool -import), but it would really help my requirements if I could use separate keystores for separate applications running in the same jvm.

I could set the keystore and truststores to be used as jvm parameters or system properties as follows:

java -Djavax.net.ssl.keyStore=serverKeys 
-Djavax.net.ssl.keyStorePassword=password 
-Djavax.net.ssl.trustStore=serverTrust 
-Djavax.net.ssl.trustStorePassword=password SSLApplication

or

System.setProperty("javax.net.ssl.keyStore","serverKeys")

But the problem with this approach is that it specifies the keystore/truststore to be used at a JVM level, thus all applications running in the same JVM gets the same keystore/truststore.

I have also tried creating a custom SSLContext and setting it as the default, but it also sets the context for all applications running in the same JVM.

SSLContext context = SSLContext.getInstance("SSL");
context.init(kms, tms, null);
SSLContext.setDefault(context);

I want to be able use different keystores/truststores without modifying individual application codes.

A solution that can dynamically register multiple key stores in addition to the default keystore/certs in jre into jvm would be great.

The solution will work in this way:

  • When JVM boots, it loads all the default certs/keystores from jre/certs folder (default java behaviour when no keystores specified).
  • When App 1 loads it registers its keystores,
  • then when App 2 loads it registers its keystores...

Please let me know your ideas or solutions. Thanks in advance!

4 Answers

Maybe I am 10 years too late to answer this question, but it could be maybe helpful for other developers too. I also ran into the same challenge of loading multiple keystores as keymaterial/trustmaterial. I discovered this page and the answer which Cody A. Ray has provided. After using the same snippet for multiple projects, I thought it would be handy to create a library and also make it publicly available to contribute back to the community. Please have a look here: Github - SSLContext-Kickstart The code snippet of Cody A. Ray for the CompositeKeyManager and CompositeTrustManager are both included.

Usage:

import nl.altindag.ssl.SSLFactory;

import javax.net.ssl.SSLContext;

public class App {

    public static void main(String[] args) {
        String keyStorePathOne = ...;
        String keyStorePathTwo = ...;
        String trustStorePathOne = ...;
        String trustStorePathTwo = ...;
        char[] password = "password".toCharArray();


        SSLFactory sslFactory = SSLFactory.builder()
                .withDefaultTrustMaterial() // loads JDK trusted certificates
                .withIdentityMaterial(keyStorePathOne, password)
                .withIdentityMaterial(keyStorePathTwo, password)
                .withTrustMaterial(trustStorePathOne, password)
                .withTrustMaterial(trustStorePathTwo, password)
                .build();

        SSLContext sslContext = sslFactory.getSslContext();
    }

}

I wasn't quite sure if I should post this here, because it could also be seen as a way to promote "my library" but I thought it could be helpful for developers.

You can add the dependency with the following snippet:

<dependency>
    <groupId>io.github.hakky54</groupId>
    <artifactId>sslcontext-kickstart</artifactId>
    <version>7.3.0</version>
</dependency>
Related