I have my own clients Private key and certificate which I have put in keystore, and servers public certificate root and intermediate I have created truststore and put them into it. I am trying to ssl handshake but not able to do so. I have below code snippet not sure what went wrong
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(keystoreStream, "mypass".toCharArray());
kmf.init(keystore, "mypass".toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
keystoreStream.close();
keystoreStream = null;
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore truststore = KeyStore.getInstance("JKS");
truststore.load(truststoreStream, "mypass".toCharArray());
tmf.init(truststore);
TrustManager[] trustManagers = tmf.getTrustManagers();
truststoreStream.close();
truststoreStream = null;
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagers, trustManagers, null);
if (urlConnection instanceof HttpsURLConnection) {
HttpsURLConnection httpURLConnection = (HttpsURLConnection) urlConnection;
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
//error on below line
httpURLConnection.connect();
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(requestData.toString());
wr.flush();
responseCode = httpURLConnection.getResponseCode();
}
}
Error -
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
The problem is caused by a certificate that is self-signed (a Certificate Authority did not sign it) or a certificate chain that does not exist within the Java truststore.
As a workaround, you can add this certificate to the list of trusted certificates of your JVM.
First you can check if your certificate is already in the truststore
by running the following command: keytool -list -keystore "$JAVA_HOME/jre/lib/security/cacerts"
(you don't need to provide a
password).
If your certificate is missing, you can get it by downloading it with your browser and add it to the truststore with the following command:
keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>
Alternatively you may refer to this thread.
It is important that you see that the correct truststore is in use.
If -Djavax.net.ssl.trustStore
has been configured, it will override
the location of the default truststore, which will need to be
checked.
Also,you may have multiple JRE/JDKs and that sometimes might be a source of confusion. Hence, make sure the certificates have been imported into the correct truststore.
Check if your Anti Virus tool has "SSL Scanning" blocking SSL/TLS. If it does, disable this feature or set exceptions for the target addresses.
Verify that the target server is configured to serve SSL correctly. This can be done with the SSL Server Test tool.
If the above fails, your truststore might be out of date. Upgrade Java to the latest version supported by your application.