Question

I had the following exception while writing to a SSL socket

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors

It seems like the certificate of the target server is not trusted. I tested my implementation on a windows 7 machine, jdk7 and tomcat7 with no problem. The Exception is thrown on ubuntu 10 LTS with openJDK 6 and tomcat7. I got the sha1 and md5 fingerprint of the sockets target server. Am I right that the certificat of the server I am trying to stream to is not trustet on my ubuntu server? can I can the fingerprint to the tomcats keystore? If so, how do I do this?

Was it helpful?

Solution

It's not the fingerprint that you need to add to your trust store, but the actual certificate.

You can add the server certificate itself or add one of the CA certificates in the chain (if you wish to trust the all the certificates from that CA, not just that particular server).

To find out what the certificate is, you can use OpenSSL:

openssl s_client -showcerts -connect your.host.name:443

(Replace the host name and 443 by the actual ports you're using.)

The blocks between --BEGIN/END CERT...-- are the certificates in PEM format. You can check their content using openssl x509 -text -noout (and pasting each block there).

Save the certificate you want to import into a plain text file (e.g. certificate.pem). You should only import certificates that you trust. There's a certain leap of faith here. (You might want to connect with your browser and check whether the key material matches, for example.)

To import into your truststore use:

keytool -importcert -keystore truststore.jks -file certificate.pem

(You may need to specify an alias wit -alias some_name_you_choose.)

If you want this to affect your default truststore, replace truststore.jks with the path to lib/security/cacerts in your Java home directory (the default password should be changeit).


Since the target server seems to come from a well-known CA anyway (and it works with some versions of the JRE), the easiest fix is certainly to update your cacerts file manually, taking a copy from a JRE with which it works. After all, as the JSSE Reference Guide says:

IMPORTANT NOTE: The JDK ships with a limited number of trusted root certificates in the /lib/security/cacerts file. As documented in keytool, it is your responsibility to maintain (that is, add/remove) the certificates contained in this file if you use this file as a truststore.

Depending on the certificate configuration of the servers you contact, you may need to add additional root certificate(s). Obtain the needed specific root certificate(s) from the appropriate vendor.


It turns out it's certainly a problem with the certificate chain order (which is incorrect on this site), as shown by Qualys SSL Labs tester.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top