I have application that using https to send data, to doing that , i implement https certificate that i grab from destination website. certificate destination website
i take 2 certificate (GeoTrust & Digicert) from website and save it to jks file using keystore explorer look like jks file
and upload it server to specific directory
In java application, i add some code to read jks file in specific path and implement certificate from application
import javax.net.ssl.HttpsURLConnection;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SSLUtils {
@Value("${ssl.keyStore.file}")
private String sslKeyStoreFile;
@Value("${ssl.keyStore.pass}")
private String sslKeyStorePass;
@Value("${ssl.trustStore.file}")
private String sslTrustStoreFile;
@Value("${ssl.trustStore.pass}")
private String sslTrustStorePass;
@Value("${ssl.host}")
private String sslHost;
/**
* Setting configuration for SSL certificate
*
*/
@Bean
public void setKeySSL(){
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> hostname.equals(sslHost));
System.setProperty("javax.net.ssl.trustStore", sslTrustStoreFile);
System.setProperty("javax.net.ssl.trustStorePassword", sslTrustStorePass);
System.setProperty("javax.net.ssl.keyStore", sslKeyStoreFile);
System.setProperty("javax.net.ssl.keyStorePassword", sslKeyStorePass);
}
}
Properties for ssl
#ssl client config
ssl.keyStore.file=/opt/ssl/keystore.jks
ssl.keyStore.pass=admin
ssl.trustStore.file=/opt/ssl/keystore.jks
ssl.trustStore.pass=admin
ssl.host=https://devapi.***********.co.id
After deploy to apache tomcat 9.0.37 , i got error "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target".
But when i run application locally with intelijj, the application running well and got response from destination , same result while run application in war file form with command java -jar which mean code for implement ssl running well too.
I am pretty sure , there is no problem with path of ssl file. I assume cause of this problem is jks file cannot read in tomcat , not invalid certification (because in local , i using same certification and its valid)
The Question is : How that can be happen ?
FYI : i also have another microservices that using same code to implement ssl and its working fine in same apache tomcat.
Some solution that i already done and its not working :
Finally, after a week struggling with this issue, i solve this problem. The problem is keystore server (destination server) contain just server certificate without root CA certificate and intermediate certificate. Thats why while handshake process made, its make failure connection. Because while connection made, server send all certificate (chain certifcate).
Please watch this lectures about SSL process made : SSL and HTTPS Lecture
Step to solve :
To do that, use InstallCert.java and run
java -Djavax.net.debug=ssl:handshake InstallCert host:port
Note : if all chain-certificate not complete (without CA certificate and intermediate) , please contact administrator server to add all certificate in server keystore.
To do that, use SSLPoke.java and run
java -Djavax.net.debug=ssl -Djavax.net.ssl.trustStore=jssecacerts SSLPoke host port
Note : If connection success, that trustore ready to use.
If it not solve your problem, you can debug your tomcat by add command in startup.sh
https://medium.com/@anuruddha.thennakoon/enable-ssl-debug-logs-in-tomcat-f9d7e0d1fd67