Search code examples
javasslhttpskeystoretruststore

How to set keystore and truststore without using System.setProperty()


I've got a client certificate in my keystore, and server's public certificate in my truststore.

Currently, I'm setting my keystore and trustore as

System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.keyStore", Constants.APPLICATION_HOME + File.separatorChar + this.certificateName);
System.setProperty("javax.net.ssl.keyStorePassword", certificatePass);

System.setProperty("javax.net.ssl.trustStore", Constants.APPLICATION_HOME + File.separatorChar + "jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");

But I want to do it without using System.setProperty(). At least the keystore part, truststore can stay this way since it never changes. I tried this:

keyStore = KeyStore.getInstance("PKCS12");

InputStream keyStoreData = new FileInputStream(Constants.APPLICATION_HOME + File.separatorChar + this.certificateName);
this.keyStore.load(keyStoreData, certificatePass.toCharArray());

TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(this.keyStore);

TrustManager[] trustManagers = trustFactory.getTrustManagers();

sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, null);
SSLContext.setDefault(sslContext);

But that's setting the truststore as far as I can see, and my handshake therefore fails because now I've only got a client certificate in my truststore, and not a server certificate from my jssecacerts file. It fails with this error:

http-bio-8080-exec-10, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

How do I achieve this?


Solution

  • This example can help you:

    import java.io.File;
    import java.io.FileInputStream;
    import java.net.InetAddress;
    
    import javax.net.ssl.KeyManagerFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManagerFactory;
    
    import java.security.KeyStore;
    
    import org.java_websocket.server.DefaultSSLWebSocketServerFactory;
    
    public class EventWebSocketSecureServer extends EventWebSocketServer {
    
        private static EventWebSocketSecureServer instance;
    
        public static EventWebSocketSecureServer instance() {
            return instance;
        }
    
        public EventWebSocketSecureServer(int port, InetAddress ip) {
            this(port, null, null, ip);
        }
    
        public EventWebSocketSecureServer(int port, String keystorepath, String keystorepassword, InetAddress ip) {
            super(port, ip);
    
            try {
                SSLContext sslContext = SSLContext.getInstance("TLS");
                char ksPassword[] = keystorepassword.toCharArray();
                if (!keystorepath.equals("")) {
                    KeyStore ks = KeyStore.getInstance("JKS");
                    ks.load(new FileInputStream(new File(keystorepath)), ksPassword);
    
                    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
                    kmf.init(ks, ksPassword);
                    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
                    tmf.init(ks);
    
                    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
                } else {
                    sslContext.init(null, null, null);
                }
                this.setWebSocketFactory(new DefaultSSLWebSocketServerFactory(sslContext));
            } catch (Exception e) {
                com.gmt2001.Console.out.println("Secure EventSocketServer failed: " + e);
                e.printStackTrace();
            }
        }
    }
    

    https://www.programcreek.com/java-api-examples/?code=GloriousEggroll/quorrabot/quorrabot-master/src/com/simeonf/EventWebSocketSecureServer.java