Issue
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 :
- Running apache tomcat in root mode same as owner of directory and file at ssl file (opt/ssl/)
- import certificate to jvm certificate
- import certificate to jvm certificate and in code read cacerts file in /usr/java/jdk1.8.0_261/jre/lib/security/cacerts
Solution
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 :
- In Client server, get certificate from server
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.
- In Client server, Check connection with trustore that just made with InstallCert.java
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
Answered By - None for Nothing
Answer Checked By - Marie Seifert (JavaFixing Admin)