unable to find valid certification path to requested target

When working on a client that works with an SSL enabled server running in https protocol, you could get error 'unable to find valid certification path to requested target' if the server certificate is not issued by certification authority, but a self signed or issued by a private CMS.

Don't panic. All you need to do is to add the server certificate to your trusted Java key store if your client is written in Java. You might be wondering how as if you can not access the machine where the server is installed. There is a simple program can help you. Please download the Java program and run

% java InstallCert _web_site_hostname_

This program opened a connection to the specified host and started an SSL handshake. It printed the exception stack trace of the error that occured and shows you the certificates used by the server. Now it prompts you add the certificate to your trusted KeyStore.

If you've changed your mind, enter 'q'. If you really want to add the certificate, enter '1', or other numbers to add other certificates, even a CA certificate, but you usually don't want to do that. Once you have made your choice, the program will display the complete certificate and then added it to a Java KeyStore named 'jssecacerts' in the current directory.

To use it in your program, either configure JSSE to use it as its trust store or copy it into your $JAVA_HOME/jre/lib/security directory. If you want all Java applications to recognize the certificate as trusted and not just JSSE, you could also overwrite the cacerts file in that directory.

After all that, JSSE will be able to complete a handshake with the host, which you can verify by running the program again.

To get more details, you can check out Leeland's blog No more 'unable to find valid certification path to requested target'

Comments:

if i use run this application (anyway if in eclipse or by commandline) all seems to be fine. it tells me that the alias is added to jssecacerts.

but it isnt. if i run the programm again it adds the certificate again to jssecacerts. and again, and again...
of course ma java applications are not able to handshake with the ca's host.

to you have an idea what could cause this problem?

Posted by Gerald Ruckendorfer on April 08, 2009 at 10:23 PM PDT #

It works for me just fine.

Posted by GC on April 20, 2009 at 11:38 AM PDT #

I am getting the error "Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target"

however when I run your tool, it says the cert is already trusted:

java InstallCert www.travelex-insurance.com
Loading KeyStore /usr/local/jdk1.6.0_14/jre/lib/security/cacerts...
Opening connection to www.travelex-insurance.com:443...
Starting SSL handshake...

No errors, certificate is already trusted

I'm stumped.

Posted by Greg Ryan on October 15, 2009 at 04:58 PM PDT #

hello,

Thank you very much to share such a great code. I wanted to ask is there any way to print Certificate validity date ( Issue on, Expire On).

Please

-Samir

Posted by Samir on April 30, 2010 at 01:17 PM PDT #

Check out javadoc of java.security.cert.X509Certificate. There are methods to get cert validity

Posted by ericow on April 30, 2010 at 01:18 PM PDT #

Thank you very much

Posted by Sreenivasan G on May 04, 2010 at 12:36 AM PDT #

thank you for sharing.

Posted by John Tee on June 24, 2010 at 08:09 PM PDT #

thank you for sharing. it is very helpful.

Posted by John Tee on June 24, 2010 at 08:10 PM PDT #

Great article. Really useful. I had a problem importing the cert, but with the code supplied by this article I done the job in couple of minutes.

Posted by Darko Petreski on August 30, 2010 at 05:57 PM PDT #

This works \*brilliantly\*, thank you. I've spent the last three hours trying to fix a problem with an application that was coming up with this error; you've saved me from spending the next three days ... or weeks ... on it. :-)

Can I ask you a quick question about it? I'd used Firefox to export the certificate of the web site that my Java program was having problems with, imported it with keytool, did a 'keytool -list' that showed that the certificate was in my special-purpose keystore - one certificate, trusted.

But I still got the error.

I ran your program, the error went away, everything works fine ... but when I do a 'keytool -list' I'm amazed to find \*forty-four\* certificates in the keystore.

Obviously that's what made the difference ... but I'm puzzled as to why. If I have the actual certificate of the web server, the one at the end of the chain, in the keystore and trusted ... I would not have thought I needed any of the others?

I obviously don't understand something, and would appreciate your giving me a quick hint if you could.

But thank you for your time-saving program!

Posted by Brad on September 13, 2010 at 09:32 PM PDT #

It is a certificate chain. Every cert in the chain is required to establish the trust.

Posted by GC on September 14, 2010 at 01:50 AM PDT #

Hi. i m imported certificate but i m getting this exception.
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]

Please help

Posted by burak on October 11, 2010 at 08:03 PM PDT #

I tried to run the tool, but it tells me

Opening connection to m2proxy.atlassian.com:443...
Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:519)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:550)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:353)
at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:71)
at InstallCert.main(InstallCert.java:83)

Any ideas?

Thanks
Kind regards

Hannes

Posted by hannes on November 11, 2010 at 07:10 PM PST #

Hi,
Running this code, I'm getting:

D:\\Development\\Egateway\\Acc18Client\\build\\classes>java InstallCert 10.99.1
1.5:9441
Loading KeyStore C:\\Program Files\\Java\\jre6\\lib\\security\\cacerts...
Opening connection to 10.99.11.5:9441...
Starting SSL handshake...

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExce
ption: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unkno
wn Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown
Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source
)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Un
known Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Sou
rce)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Sou
rce)
at InstallCert.main(InstallCert.java:99)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find vali
d certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown So
urce)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(
Unknown Source)
at InstallCert$SavingTrustManager.checkServerTrusted(InstallCert.java:18
8)
... 9 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown
Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 15 more

Server sent 1 certificate(s):

1 Subject CN=egateway.co.nz, OU=ICT Production, O=Cor
poration, L=Wellington, ST=Wellington, C=NZ
Issuer CN=egateway.co.nz, OU=ICT Production, O=Cor
poration, L=Wellington, ST=Wellington, C=NZ
sha1 5d f9 6e 78 eb 34 7f 97 cd 00 ab 84 6d 26 1f d2 0f b4 0f 20
md5 a5 b3 41 1d b0 f5 7e 83 b1 de 16 da ac 5e d1 3b

Enter certificate to add to trusted keystore or 'q' to quit: [1]

Any ideas?

Posted by Glenn on November 15, 2010 at 11:44 AM PST #

I am getting the same error as Glenn.

Posted by Shishir on November 16, 2010 at 02:06 PM PST #

Pay attention to the last line:

Enter certificate to add to trusted keystore or 'q' to quit: [1]

At this point, you need to hit "Enter" to add this cert to your keystore. This will cause this error to go away.

Thanks to the author for the post. I'm yet to figure out how to do the same but for my Tomcat - so it likes that dodgy cert too...

Posted by Stas on November 17, 2010 at 06:30 AM PST #

Yeah, I noticed that. Got past that.

The problem I have now is that because the dev server uses a self-signed certificate, it's throwing
java.security.cert.CertificateException: No subject alternative names present

To get around it I've had to set the default Hostname Verifier to an instance of a fake class that trust all hostnames.
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
// Always return true indicating that the host name is an acceptable match
// with the server's authentication scheme.
return true;
}
});

Any ideas on this one?

Posted by Glenn on November 17, 2010 at 11:06 AM PST #

Thanks!! This solved my problem and saved me many working hours!

Posted by finkx on December 01, 2010 at 08:49 PM PST #

Thanks very much. This was PERFECT !!!

Posted by Felipe on December 07, 2010 at 11:22 AM PST #

Thank You! This made my day!

Concerning to the comment of Greg Ryan (Comment No 2) I have to say I was facing the same problem.
The certificate was added to the keystore "jssecacerts" but my application still uses the keystore $JAVA_HOME/jre/lib/security/cacerts .

There are two solutions for this problem

1.) Replace the cacerts in $JAVA_HOME/jre/lib/security/ by the new keystore "jssecacerts" (like mentioned in the introduction)

2.) If you want to change the keystore at runtime you have to bind the keystore:

System.setProperty("javax.net.ssl.keyStore", <path to the new keystore>);
System.setProperty("javax.net.ssl.keyStorePassword",<password of the keystore>);
System.setProperty("javax.net.ssl.trustStore",<path to the new keystore>);

Hope this will help if somebody faces the same problem.

Posted by Matthew on December 07, 2010 at 09:08 PM PST #

NOvembro

Posted by jota@yahoo.com.br on January 06, 2011 at 03:02 AM PST #

I think many people just got too excised when the program run and forgot the last step:

"To use it in your program, either configure JSSE to use it as its trust store or copy it into your $JAVA_HOME/jre/lib/security directory. If you want all Java applications to recognize the certificate as trusted and not just JSSE, you could also overwrite the cacerts file in that directory."

I missed it initially and now everything is working as expected. Thanks again.

Posted by Eddie on January 07, 2011 at 08:21 AM PST #

Hi...
Thank you for sharing.

Posted by Rojan on January 13, 2011 at 05:49 PM PST #

People I have strugle with that same error
and I wrote how to solve it in my blog

http://felipeferreira.net/?p=974

Posted by Felipe Ferreira on January 19, 2011 at 01:19 AM PST #

THANK U SOOO MUCH!!!

Saved my life, or at least my sanity with your cute little InstallCert App!!!

Posted by RAFFGIER on January 25, 2011 at 02:53 AM PST #

You just saved my sanity too. Thank you for this excellent tool!

Posted by Isaac on January 28, 2011 at 10:55 AM PST #

Hi

I tried all the suggestions above. But it is not working for me.

I tried generating the cert file as you said. It got generated successfully. But I am still getting the below exception when i access my URL

org.springframework.web.client.ResourceAccessException: I/O error: sun.security.validator.ValidatorException: 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: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target (NativeException)

Can any one help me

Posted by Ramya on February 11, 2011 at 03:55 AM PST #

While trying to get Hudson to work against an SSL-based LDAP, I followed all the steps above, no luck though. Tool showed certs are installed, Hudson didnt pick it up.
The solution: copy the generated jssecacert file to the file ~/.keystore. By default trusted certs are apparently looked up from this file.
hth

Posted by Erich Eichinger on March 02, 2011 at 01:26 AM PST #

Thank you

I'd done this years before but I hadn't been able to configure it propertly in mac. Thanks for put me in the right direction. I've put the jssecacerts in correct folder already.

Posted by Wilson on March 07, 2011 at 05:18 AM PST #

Hi All,

I was also facing the same issue. The problem was that I have jssecacerts file in the jdk/jre security folder along with the out of the box cacerts file that is always available in the jdk/jre security folder. However, I created the certificate and added the entry in cacerts file instead of jssecacerts.

The thing is that if the file jssecacerts exists, then cacerts is not consulted. So that was the issue. After adding the certificate in jssecacerts it worked. Read this: http://tp.its.yale.edu/pipermail/cas/2007-June/005235.html.

Hope this helps!

Thanks

Posted by Muzammil Mohsin Shaikh on March 12, 2011 at 02:24 PM PST #

I found this link helpful to get the certificate out of jssecacerts and into my JVM's cacerts.
http://www.grim.se/guide/jre-cert

Also -- if you're in a test environment and don't want to be "bothered" with all of that certificate stuff, you can bypass the process with the information here:
https://svn.apache.org/repos/asf/webservices/xmlrpc/trunk/src/site/apt/ssl.apt
But use that with caution as described in the link text.

Posted by Don Albertson on April 22, 2011 at 03:06 AM PDT #

Amazing, thanks for your amazing code!!!

Just had to comment and say thank you!

Best regards!

Posted by Alan Joh Hayashi on April 28, 2011 at 01:28 AM PDT #

Post a Comment:
Comments are closed for this entry.
About

gc

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today