java - path to trustStore - set property doesn't work?
Asked Answered
P

5

58

I've setup a self-signed certificate to test an ssl java connection - however, it is refusing to locate the java trustStore. I've saved copies of it in /Java/jre6/lib/security in addition to the folder where the classes are compiled to (im using netbeans) and also to /java/jre6/bin none of the above appears to work, because when i run the following - trustStore = null.

public class ShowTrustStore {

    public static void main(String[] args) {

        System.setProperty("javax.net.ssl.keyStore", "keystore.jks");
        System.setProperty("javax.net.ssl.trustStrore", "cacerts.jks");
        System.setProperty("javax.net.ssl.keyStorePassword", "changeit");



        String trustStore = System.getProperty("javax.net.ssl.trustStore");
        if (trustStore == null) {
            System.out.println("javax.net.ssl.trustStore is not defined");
        } else {
            System.out.println("javax.net.ssl.trustStore = " + trustStore);
        }
    }
}

how to set the path correctly?

**********UPDATE************ Using the getFile() method and some more debug data:

package ssltest;

public class Main {

    public static void main(String[] args) {

//        System.setProperty("javax.net.ssl.keyStore", "/keystore.jks");
//        System.setProperty("javax.net.ssl.trustStrore", "/java.home/cacerts.jks");
//        System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
//        System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

        try {
            Main.class.getResource("trustStore.jks").getFile();
        } catch (Exception e) {
            e.printStackTrace();
        }

        String trustStore = System.getProperty("javax.net.ssl.trustStore");

        if (trustStore == null) {
            String storeLoc;
            storeLoc = System.getProperty("java.class.path");
            System.out.println("classpath: " + storeLoc);
        }

        trustStore = System.getProperty("javax.net.ssl.trustStore");
        if (trustStore == null) {
            System.out.println("javax.net.ssl.trustStore is not defined");
        } else {
            System.out.println("javax.net.ssl.trustStore = " + trustStore);
        }
    }
}

run: java.lang.NullPointerException classpath: C:\Users\Main\Documents\NetBeansProjects\sslTest\build\classes;C:\Users\Main\Documents\NetBeansProjects\sslTest\src at ssltest.Main.main(Main.java:15) javax.net.ssl.trustStore is not defined BUILD SUCCESSFUL (total time: 0 seconds)

Pean answered 26/1, 2010 at 9:48 Comment(1)
Good to know that I'm not the only one whose searching a bug hour for hour ... because of a little typo ... ;-)Goshawk
O
80

You have a typo - it is trustStore.

Apart from setting the variables with System.setProperty(..), you can also use

-Djavax.net.ssl.keyStore=path/to/keystore.jks
Overdone answered 26/1, 2010 at 10:6 Comment(7)
im not sure what else i can try - ive got the java.home value as C:\Program Files (x86)\Java\jdk1.6.0_17\jre now even if i store the two files here and run this: System.setProperty("javax.net.ssl.keyStore", "/java.home/keystore.jks"); System.setProperty("javax.net.ssl.trustStrore", "/java.home/cacerts.jks"); it still doesnt find them...Pean
java.home isn't resolved as a path. you can get it via System.getProperty("java.home"), but it isn't advisable to put the keystore there. Besides, I've given you three options - try them.Overdone
i've tried using both - the first doesnt work and second method throws a null pointer exception - ive added the code and the debug info above. ive stored the files at both of these locations (which show up as the classpath): C:\Users\Main\Documents\NetBeansProjects\sslTest\build\classes;C:\Users\Main\Documents\NetBeansProjects\sslTest\src any ideas whats going wrong? thanks!!Pean
If i add these lines: System.setProperty("javax.net.ssl.keyStore", "C:/Users/Main/Documents/NetBeansProjects/sslTest/stores/keystore.jks"); System.setProperty("javax.net.ssl.trustStrore", "C:/Users/Main/Documents/NetBeansProjects/sslTest/stores/cacerts.jks"); I still get the same error - namely: run: classpath: C:\Users\Main\Documents\NetBeansProjects\sslTest\build\classes;C:\Users\Main\Documents\NetBeansProjects\sslTest\src javax.net.ssl.trustStore is not defined BUILD SUCCESSFUL (total time: 0 seconds)Pean
@Pean - I notice that your comment says you set a property called "javax.net.ssl.trustStrore". Close ... but no cigar.Preachment
@Overdone The issue isn't setting on the command line versus at runtime -- it was just a typo. You don't have to set it on the command line -- works fine either way.Erminna
No, he haven't anything with a keyStore to do. He needs to create a trustStore, and not a keyStore.Bucher
H
47

Looks like you have a typo -- "trustStrore" should be "trustStore", i.e.

System.setProperty("javax.net.ssl.trustStrore", "cacerts.jks");

should be:

System.setProperty("javax.net.ssl.trustStore", "cacerts.jks");
Haulage answered 26/1, 2010 at 18:12 Comment(1)
It worked for me by using -Djavax.net.ssl.trustStore=/home/path/to/truststore with Tomcat8Zephan
F
13

Both

-Djavax.net.ssl.trustStore=path/to/trustStore.jks

and

System.setProperty("javax.net.ssl.trustStore", "cacerts.jks");

do the same thing and have no difference working wise. In your case you just have a typo. You have misspelled trustStore in javax.net.ssl.trustStore.

Fagen answered 12/9, 2013 at 14:28 Comment(2)
Not true, misleading. A trustStore is a clientside container for the public keys of trusted servers, while keyStore is a container of your private keys.Bucher
@Bucher Not true, misleading. A truststore s a client- or server- side container for certificates of trusted signers.Subkingdom
R
3

As pointed out by others, there's a typo in the property.

Another way to check whether JVM is using the configured trustStore is to add the property: -Djavax.net.debug=all , which will turn on the debug message.

After the app starts, it will print out a message like:

javax.net.ssl|DEBUG|11|parallel-1|2021-04-17 21:25:13.827 CST|TrustStoreManager.java:112|trustStore is: C:/path/to/the/trustStore

Then we can tell whether it's using the one we want or the default one comes with the JDK.

Reference
Rind answered 17/4, 2021 at 13:34 Comment(1)
Thanks for this hint. This way I found out I was using a trust store in PKCS12 format, not in JKS. I needed to add -storetype JKS to my keytool command creating the trust store.Incarnadine
E
2

Alternatively, if using javax.net.ssl.trustStore for specifying the location of your truststore does not work ( as it did in my case for two way authentication ), you can also use SSLContextBuilder as shown in the example below. This example also includes how to create a httpclient as well to show how the SSL builder would work.

SSLContextBuilder sslcontextbuilder = SSLContexts.custom();

sslcontextbuilder.loadTrustMaterial(
            new File("C:\\path to\\truststore.jks"), //path to jks file
            "password".toCharArray(), //enters in the truststore password for use
            new TrustSelfSignedStrategy() //will trust own CA and all self-signed certs
            );

SSLContext sslcontext = sslcontextbuilder.build(); //load trust store

SSLConnectionSocketFactory sslsockfac = new SSLConnectionSocketFactory(sslcontext,new String[] { "TLSv1" },null,SSLConnectionSocketFactory.getDefaultHostnameVerifier());

CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsockfac).build(); //sets up a httpclient for use with ssl socket factory 



try { 
        HttpGet httpget = new HttpGet("https://localhost:8443"); //I had a tomcat server running on localhost which required the client to have their trust cert

        System.out.println("Executing request " + httpget.getRequestLine());

        CloseableHttpResponse response = httpclient.execute(httpget);
        try {
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());

            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    } finally {
        httpclient.close();
    }
Elaterid answered 18/6, 2019 at 10:41 Comment(2)
this is the only thing that worked for me on connections made from a remote server which I had no direct access to. I ended up injecting the SSLSocketConnectionFactory into a Spring Rest Template and it worked like a charm. Thanks!Rodgerrodgers
if you would have provided the imports that would be much betterLaurasia

© 2022 - 2024 — McMap. All rights reserved.