Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PKIX path building failed in Java application

I have been struggling for almost one week to get my applications up running after moving my applications from Windows 2000 to Windows 2008 R2 Server.

The procedure:

  1. Installed Java JDK 1.7.0_25
  2. Set system environment variable JAVA_HOME to C:\Progra~1\Java\jdk1.7.0_25\
  3. Imported the certificate into cacerts with keytool
  4. Ensured that the certificate exists in keytool with -list.

I have tried to repeat step 3 with InstallCert to ensure that i havent messed anything up.

The above methods did not solve my problem, so i tried to do it programmatically:

System.setProperty("javax.net.ssl.trustStore", "C:/Progra~1/Java/jdk1.7.0_25/jre/lib/security/cacerts"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 

Still without any luck. I am stuck and not quite sure which direction to go from here.

Stack trace:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target     at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)     at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886)     at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)     at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)     at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)     at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)     at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)     at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)     at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)     at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)     at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)     at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)     at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515)     at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)     at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)     at util.SMS.send(SMS.java:93)     at domain.ActivationSMSSenderMain.sendActivationMessagesToCustomers(ActivationSMSSenderMain.java:80)     at domain.ActivationSMSSenderMain.<init>(ActivationSMSSenderMain.java:44)     at domain.ActivationSMSSenderMain.main(ActivationSMSSenderMain.java:341) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target     at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)     at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)     at sun.security.validator.Validator.validate(Validator.java:260)     at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)     at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)     at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)     at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)     ... 14 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target     at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)     at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)     at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)     ... 20 more 

UPDATE:

Both System.out.println(System.getProperty("javax.net.ssl.trustStore")); and System.out.println(System.getProperty("javax.net.ssl.keyStore"));

returns null.

like image 791
JavaCake Avatar asked Aug 22 '13 11:08

JavaCake


People also ask

What does Pkix path building failed mean?

This type of error typically means that your network is using a self-signed certificate. To make CopyStorm (or any other Java based application) work with your certificate, you must add the certificate to Java's trusted store file “cacerts”. To add the certificate: Get a copy of your certificate.

What is Pkix certificate?

PKIX stands for Public Key Infrastructure X509. Whenever Java attempts to connect to another application over SSL, the connection will only succeed if it can trust the application. In Java, trust is handled with a keystore, also known as the truststore (typically <agent_home>/<version_number>/conf/cacerts.

What is Sun Security Validator ValidatorException?

If Server returns a certificate that cannot be validated against the certificates a browser or Java client holds in its truststore then it throws the "sun. security. validator. ValidatorException: PKIX path building failed: sun.


2 Answers

I ran into similar issues whose cause and solution turned out both to be rather simple:

Main Cause: Did not import the proper cert using keytool

NOTE: Only import root CA (or your own self-signed) certificates

NOTE: don't import an intermediate, non certificate chain root cert

Solution Example for imap.gmail.com

  1. Determine the root CA cert:

    openssl s_client -showcerts -connect imap.gmail.com:993 

    in this case we find the root CA is Equifax Secure Certificate Authority

  2. Download root CA cert.
  3. Verify downloaded cert has proper SHA-1 and/or MD5 fingerprints by comparing with info found here
  4. Import cert for javax.net.ssl.trustStore:

    keytool -import -alias gmail_imap -file Equifax_Secure_Certificate_Authority.pem 
  5. Run your java code
like image 86
jb1 Avatar answered Sep 29 '22 08:09

jb1


You've imported the certificate into the truststore of the JRE provided in the JDK, but you are running the java.exe of the JRE installed directly.

EDIT

For clarity, and to resolve the morass of misunderstanding in the commentary below, you need to import the certificate into the cacerts file of the JRE you are intending to use, and that will rarely if ever be the one shipping inside the JDK, because clients won't normally have a JDK. Anything in the commentary below that suggests otherwise should be ignored as not expressing my intention here.

A far better solution would be to create your own truststore, starting with a copy of the cacerts file, and specifically tell Java to use that one via the system property javax.net.ssl.trustStore.

You should make building this part of your build process, so as to keep up to date with changes I the cacerts file caused by JDK upgrades.

like image 35
user207421 Avatar answered Sep 29 '22 08:09

user207421