I have a java keystore with which I can connect to a protected https third-party service. I use this keystore explicitely in my code when I initialize my web client:
Accordingly to the answer of @Bruno in How to acess jvm default KeyStore? there is no default KeyStore
in java.
That means that if you run the app with
-Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.keyStore=/opt/app/certificates/keyStore.jks
this will also require to parse them in your code like
private static final String filePath = System.getProperty("javax.net.ssl.keyStore");
private static final String password = System.getProperty("javax.net.ssl.keyStorePassword");
and then use explicitly in your HttpClient
(like in Solution #1
).
In other words, just specifying the properties for keyStore
is useless if you will not parse them manually and not use them for your HttpClient
. This is what I was trying to understand when I had posted my question.
This is an important difference from system properties for TrustStore
like
-Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStore=/opt/app/certificates/cacert
Specifying these properties does not require any extra code. As there is a default TustStore
which will be created automatically by JVM
from the properties. An then httpClient
will just use that default TrustStore
without any efforts from a developer.
You can do something like the first solution, but you have to remove the password as a String
, the password should be either in your properties
file that is loaded at runtime, or specify it as an environment variable when you start the JVM.
I would say that the main point is that the password should not be in the code.
For the second solution you might want to check the trustStore
environment variables.
https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslserver.html
Set the truststore javax.net.ssl.trustStore
for the public cert to provide to the external service. javax.net.ssl.keyStore
is for storing your private cert when running on https.
// Your private cert location
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.keyStore", env.getProperty(SSL_KEYSTORE));
System.setProperty("javax.net.ssl.keyStorePassword", env.getProperty(SSL_KEYSTORE_PASS));
// Public cert location
System.setProperty("javax.net.ssl.trustStoreType", "pkcs12");
System.setProperty("javax.net.ssl.trustStore", env.getProperty(SSL_TRUSTSTORE));
System.setProperty("javax.net.ssl.trustStorePassword", env.getProperty(SSL_TRUSTSTORE_PASS));
Also, I would recommend loading the properties (especially passwords) from a separate properties file, as mentioned by Léo Schneider.
UPDATE
To your question regarding usefulness of javax.net.ssl
properties, these properties are an alternative to define the truststore and keystore properties. It is useful b/c not all libraries allow for SSLContext as input where it may be needed (for example legacy libraries that don't support ssl). Furthermore, these properties can also be defined directly from the command line, increasing usability.