Adobe Solution Partner

February 9, 2007

Troubleshooting javax.net.ssl.SSLHandshakeException

Filed under: ColdFusion — Tags: , — Daryl Banttari @ 6:55 am

Concepts

People often think of SSL as a form of encryption. Strictly speaking, it’s not; SSL is a protocol or “cryptosystem” that uses existing encryption algorithms in a way that ensures privacy. To that end, SSL is not just about encryption; it’s also about authentication, ensuring that you’re connecting to the party you think you’re connecting to. This is done using a chain of trust; effectively, you trust “certificate authorities” (CAs) to use due diligence in ensuring that SSL public keys belong to the party you’re connecting to.

The combination of a public key, the trust information about that key, and the digital signature of the CA, is known as a “SSL Certificate”, and that certificate is sent by an SSL server to a client at the beginning of every conversation.

Embedded in every SSL certificate is the “common name” of the resource that the certificate is for, which, in SSL, is the name of the server as you type it into a browser. For example, one of the “common names” for the SSL certificate at paypal.com is “www.paypal.com”. If you try to make an SSL connection to paypal.com based on IP address, your browser will pop up a warning that the name you typed doesn’t match the name in the SSL certificate.

It can be argued that the “real” chain of trust extends back to the browser, however, since the list of trusted CAs (and their public keys) are distributed with the browser.

For Java, this list of trusted CAs is (usually) stored in a file called “cacerts”. Unlike with a browser, however, if either (a) the common name doesn’t match the name in the URL, or (b) the CA that signed the SSL certificate isn’t in the list of trusted CAs, then the SSL communication fails with an exception similar to this:

javax.net.ssl.SSLHandshakeException

There is no “workaround” for this to disable the authentication step; the CA for the SSL cert must be trusted, and the common name must match, or the SSL connection will fail.

Common Name Mismatch

Fixing a common name mismatch is simple; just ensure that the host name in the URL you’re using for communication matches one of the common names in the SSL certificate. If you double-click on the “key” in a browser after connecting to any page on the SSL server, you can view the list of common names that the certificate applies to.

Unknown Certificate Authority

The default certificate store that’s shipped with the JVM is called “cacerts”, and is typically stored in the JRE’s ./lib/security folder, unless you’re using the “-Djavax.net.ssl.trustStore=” JVM parameter to explicitly load a different list of CA certificates.

If a trusted CA is not found in the SSL certificate, you get an exception similar to this:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found

This can have one of two root causes:

File not found

If the trusted CA certificate list isn’t in the default location, nor at the location specified using the “-Djavax.net.ssl.trustStore=” JVM parameter, a “file not found error” is not produced; the symptom is that all SSL communication fails. For this reason, if using JVM args to specify an alternate trusted CA list file, only absolute paths should be used, as the use of relative paths is rather unreliable.

The CA isn’t in the trusted CA list

If the party you’re connecting to has recently changed server hardware or updated their SSL certificate, it’s possible that they’ve started using a CA that isn’t in your trusted list. Before continuing, verify that one of these things has occurred, and that you’re not seeing the effects of some sort of man-in-the-middle attack, where someone is trying to decrypt and reencrypt communications using a fake SSL certificate. (The odds of actually experiencing such an attack are vanishingly small, but cannot be discounted altogether.)

If the CA isn’t in the trusted CA list, but should be, you can import it into the list. Step one is saving the CA’s public key into a file; step two is importing that file into our trusted CA list.

You SHOULD get the CA’s new public key directly from the CA’s website; however, if this is not an option (and you’re really sure you’re not seeing the side effect of a man-in-the-middle attack) you can use Internet Explorer to extract the CA public key into a file that can be imported into Java’s cacerts file.

Saving the CA public key into a file:

(These directions are from http://www.webmilhouse.com/7b/?p=85 )

Steps in IE 6.0 on Windows 2000 to get the cert:

  1. Connect to https://my.domain.com
  2. Go to Tools > Internet Options > Content > Certificates > Intermediate Certification Authorities [or "Trusted Root Certification Authorities"]
  3. Choose “Thawte SGC CA” [or whichever is needed]
  4. Click “Export…”, then “Next>”
  5. Select “DER encoded binary X.509 (.CER)”
  6. Name the file thawtesgcca.cer [change the name as applicable]
  7. Select “Finish”
Importing the CA public key into the trust list (file and alias names will likely vary; the alias name isn’t important):
j2sdk1.4.2_12binkeytool -keystore j2sdk1.4.2_12jrelibsecuritycacerts -import -alias thawtesgc -file thawtesgcca.cert -trustcacerts

Note that you must have a full JDK installed (not just the JRE) to have access to keytool and javac (used below).

Testing your New Cacerts

Here is a simple Java class that can be used to test SSL connections:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

/**
 * @author Daryl Banttari
 *
 */

public class TestSSL {

    public static void main(String[] args) {
        // default url:

        String urlString = "https://www.paypal.com/";

        // if any url specified, use that instead:

        if(args.length > 0) {
            urlString = args[0];
        }
        System.out.println("Connecting to " + urlString + "...");
       
        try {
            // convert user string to URL object

            URL url = new URL(urlString);

            // connect!

            URLConnection cnx = url.openConnection();
            cnx.connect();

            // read the page returned

            InputStream ins = cnx.getInputStream();
            BufferedReader in = new BufferedReader(new InputStreamReader(ins));
            String curline;
            while( (curline = in.readLine()) != null ) {
                System.out.println(curline);
            }

            // close the connection

            ins.close();
        }
        catch(Throwable t) {
            t.printStackTrace();
        }

    }
}

Save this code into a file named TestSSL.java (case sensitive!) and compile:

j2sdk1.4.2_12binjavac TestSSL.java

Now run it to attempt to load the target URL:

j2sdk1.4.2_12jrebinjava TestSSL https://www.paypal.com/

Either the contents of the page will be displayed, or an exception will be shown indicating why the page could not be retrieved.

SSL: Not Just About Encryption!

Remember, it’s not enough to encrypt communication, you also have to be sure you’re communicating with the right person. SSL, and all good public key cryptosystems, ensure not only encryption but also authentication. Since you can’t manually authenticate every SSL certificate to every company that runs an SSL server, you trust other certificate authorities to ensure that the server you’re connecting to is the server you think you’re connecting to. If Java doesn’t trust the certificate authority used by the SSL server, then Java will refuse to talk to that server.

Browsers will pop up a warning dialog indicating that there’s a problem if the CA isn’t trusted, but Java can’t assume anyone is watching for that, so it throws an exception and fails. Updating the cacerts file used by Java, so that it includes the new certificate authority’s public key, will solve that issue.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Technorati
  • TwitThis

23 Comments »

  1. Daryl,

    Great summary and writeup about ssl and how it pertains to encryption! I’ve been struggling with this very issue and your post solved the problem.

    Thanks!!
    CJ

    Comment by Charles Jackson — September 19, 2007 @ 12:00 am

  2. when i am trying to access the webservice over ssl i.e. on https, i m getting "connection refused" exception. while i able to access the same over http.

    I have already imported the ssl certificate on my cacerts file, still don’t know what could be the showstopper.

    If any of you could provide me some hand holding that would be a great help.

    Note that i m using WAS5.1 and WSAD5.1 for deployment & development purposes.

    Thanks
    abhishek

    Comment by abhishek khandelwal — November 6, 2007 @ 12:00 am

  3. Abhishek,

    It sounds like there’s a problem reaching the server via SSL. The first step would be to use a regular browser *running on the server consuming the Web service* and try to access the WSDL for the Web service that way. It’s probable that there’s a firewall access policy preventing communication.

    –Daryl

    Comment by Daryl Banttari — November 29, 2007 @ 12:00 am

  4. Great summery, i was able to solve my issue when i read this article (file not found error)

    Comment by kiran — December 20, 2007 @ 12:00 am

  5. Hi

    I am having problems even though i imported the certificate to the keystore .I keep getting this error :

    Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found

    Please help

    Comment by Ajay — July 16, 2008 @ 12:00 am

  6. Thanks a lot Daryl, I resolved the problem.

    Comment by Abhishek Khandelwal — October 21, 2008 @ 12:00 am

  7. Thank you! Awesomely clear.

    Comment by Marion Andrin — December 16, 2008 @ 12:00 am

  8. Brilliant summary and description. Helped with an issue I’ve spent an 18 hour day chasing.

    Thanks.

    Comment by Dawn Ahukanna — January 7, 2009 @ 12:00 am

  9. So are CAs a little like cyber-notaries?

    Comment by Gabe — June 20, 2009 @ 6:12 pm

  10. Hi,

    I have jboss in clustered environment,

    I call httpURL connection to connect to the remote site, and pass certificate, all goes well for some time, means one or to days, after that I start recieving

    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found.

    The example class you have supplied, also works well, but with Jboss cluster it stops working after few days.

    Thanks in advance.

    Regards,
    Navkalp

    Comment by navkalp — August 31, 2009 @ 7:28 am

  11. Thanks for the brilliant summary.Helped me resolve my issue with certificates handling.
    Thanks for sharing

    Also some useful information @ http://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/keytool.html#cacerts also.

    Comment by Prashanth — September 7, 2009 @ 7:49 am

  12. great help thank you very much…. i ve been working on this on several days, this writeup was very useful thanks…

    Comment by BADDI Mbarek — September 10, 2009 @ 12:00 pm

  13. Thank you very much, was very very useful !

    Comment by Julian — November 4, 2009 @ 5:42 pm

  14. I am getting this error: javax.net.ssl.SSLHandshakeException: no cipher suites in common

    What is the meaning of the error: “no cipher suites in common”?

    I am connecting from my ssl-enabled client to a ssl-enabled server (which someone else has developed). What is the way to fix this? Any hints please.
    Thanks.

    Comment by Mitra — December 4, 2009 @ 7:06 am

  15. Note that the command to import the certificate in the java default keystore will still ask for a password. Unless you sys admin has changed it, it is “changeit”

    Comment by Rishabh — March 25, 2010 @ 7:18 pm

  16. Thank you for the clear and concise explanation. I googled this exception and yours is the best one! Keep on bloggin’ :)

    Comment by cafeLiberty — August 5, 2010 @ 2:13 pm

  17. [...] http://www.webapper.com/blog/index.php/2007/02/09/troubleshooting-javaxnetsslsslhandshakeexception/ [...]

    Pingback by javax.net.ssl.SSLHandshakeException « Oracle DBA ve Apps DBA blog — August 31, 2010 @ 4:56 am

  18. [...] the SSL communication fails with an exception similar to this: javax.net.ssl.SSLHandshakeException See the original for Detail [...]

    Pingback by Troubleshooting javax.net.ssl.SSLHandshakeException - grails error installing plugin javax.net.ssl.sslhandshakeexception — September 23, 2010 @ 6:34 am

  19. Thankz for ur valuable informations regarding SSL
    From this I got solution for my problems in SSL enabled site

    Comment by Raghu — December 16, 2010 @ 2:13 am

  20. This was a very consise and usful article.

    For those still having trouble

    Starting the client jvm with

    -Djavax.net.debug=all

    on the command line will help debug the SSL handshake. It shows the path to the trust store being used
    and lists the trusted certs.

    Comment by Tony Cavaciuti — April 13, 2011 @ 4:42 am

  21. Excellent article! It helps me understand some of the SSL issues we had been facing.

    Comment by Karun — June 7, 2011 @ 11:56 am

  22. Hi,
    SSL handshake exception in server .(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)
    We have a 4 server in production and we need to send some file to third party.We have a valid certificate for that.
    Sometime we are able to send files to third party through 2 of this server.
    But sometime 4 of the server failed and need to restart server frequently.
    So anybody can help me to find out the root cause of the issue.I will add if any details need for this.

    Thanking You

    Comment by Liya — September 17, 2012 @ 4:11 am

  23. hi

    your troubleshooting javax.net.ssl.SSLHandshakeException is very helpful to me . Thank you so much . i really like to troubleshoot especially in software . I also have a blog that something related to troubleshooting in socket error .

    Comment by Sanny Jane Yacapin — December 3, 2013 @ 5:33 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

 

Server Down?

Maximize Web application uptime by drawing upon Webapper's years of experience tuning and stabilizing many of the world's largest ColdFusion Web applications. Contact us today!