SSLHandshakeException when multiple ssl connections
-
28-05-2021 - |
Question
I wrote a module that connects to service over https with authentication. After setting proper path to keystore it works fine. There is a problem when I want to use that module (as a jar) in my Tomcat application. I set proper paths (absolute paths) to keystore as well but when I try to connect I get handshake exception
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
As I remember I got this message before when I had incorrect keystore. Do I need to do anything more with that to make it work under Tomcat. Any other issue I missed? I connect to another service over https without authentication and this works fine (in Tomcat app).
edit: The problem was to run a project that connects to different services through ssl (not only in Tomcat). One with authentication, second without. So I edited the title
Solution 2
Once again I'm giving answer to myself. After reading How to control SSLContext scope I decided to do the same and it works fine. By default I don't set any trustStore (so default cacerts is used) and when I need to authenticate I use
httpsUrlConnection.setSSLSocketFactory(getSSLContext().getSocketFactory());
when getSSLContext() returns what I wrote above (without setDefault)
I would like to know how to change default SSLContext in Tomcat app so if anyone could help I would be thankful
OTHER TIPS
Setting multiple truststore on the same JVM gave me an answer. I needed only to set my key factory as well as trust factory and it works :)
System.setProperty doesn't set ssl property that is already set.
// load your key store as a stream and initialize a KeyStore
InputStream trustStream = new FileInputStream("Resources/keystore.ImportKey");
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
// if your store is password protected then declare it (it can be null however)
String trustPassword = "changeit";
// load the stream to your store
trustStore.load(trustStream, trustPassword.toCharArray());
// initialize a trust manager factory with the trusted store
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore);
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(trustStore, trustPassword.toCharArray());
// get the trust managers from the factory
TrustManager[] trustManagers = trustFactory.getTrustManagers();
KeyManager[] keyManagers = keyFactory.getKeyManagers();
// initialize an ssl context to use these managers and set as default
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagers, trustManagers, null);
SSLContext.setDefault(sslContext);
just works fine!