I\'m building two java applications which have to communicate using SSL two way authentication, I used instructions from here to create client and server certificates.
then
after spending a long time to make this work, the solution is as follows:
first when setting the properties using System.put("key", "value") I noticed after many tries it is not setting the KeyStore value it is does not appear in the ssl log , also tried to set the properties as parameters in the tomcat configuration using -Djavax.net.ssl.keyStore="" this also didn't work.
so I read the KeyStore from an InputStream like this:
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream io = new FileInputStream("path/to/jks/file.jks");
try{
keystore.load(io, "pass".toCharArray());
} finally {
io.close();
}
and use the same previous code to read the TrustStore like :
KeyStore trustStore= KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream stream = new FileInputStream("path/to/truststore/file.jks");
try{
keystore.load(stream, "trusted".toCharArray());
} finally {
stream.close();
}
after that define the SSLContext :
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keystore, "keyPassword".toCharArray())
.loadTrustMaterial(truststore, new TrustSelfSignedStrategy())
.build();
loadKeyMaterial used to load the keyStore it takes the password of your privateKey "keyPassword" as a parameter, so you must protect the private key using a password, when I tried to use a plain private key not encrypted "protected" with a password, I get exception which says: java.security.UnrecoverableKeyException: Cannot recover key, by default this is the same as the keystore password unless you changed it.
then create the SSLConnectionSocketFactory and pass it as a parameter to the HttpClient ..
this worked for me :)