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 :)