PKIX path building failed in Java application

2019-01-16 16:37发布

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.

5条回答
放我归山
2楼-- · 2019-01-16 16:52

In my case the issue was resolved by installing Oracle's official JDK 10 as opposed to using the default OpenJDK that came with my Ubuntu. This is the guide I followed: https://www.linuxuprising.com/2018/04/install-oracle-java-10-in-ubuntu-or.html

查看更多
够拽才男人
3楼-- · 2019-01-16 16:54

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
查看更多
萌系小妹纸
4楼-- · 2019-01-16 16:55

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.

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-01-16 16:56

Per your pastebin, you need to add the proxy.tkk.com certificate to the truststore.

查看更多
萌系小妹纸
6楼-- · 2019-01-16 17:12

If you are using Eclipse just cross check in Eclipse Windows--> preferences---->java---> installed JREs is pointing the current JRE and the JRE where you have configured your certificate. If not remove the JRE and add the jre where your certificate is installed

查看更多
登录 后发表回答