Java HTTPS to a server with a self-signed certificate

Nothing is easy in Java, and nothing is more disproportionately non-easy than downloading something. If you add SSL to the equation, it becomes unfeasible for any human to navigate the twisted passages of the Java API, so here is a tiny fragment of map I have pieced together using the Internets.

If you have a server that you want to download something from, and you need to use SSL (i.e. your URL starts with “https://”), and it has a self-signed certificate, you will need to get hold of a “trust store” file (a .jks file) that tells Java it can trust your server. How to get hold of this file is out of the scope of this blog post, by which I mean I don’t know how you get one.

Assuming you have somehow magicked up a trust store file (let’s call it trust.jks), and you know the password for it (let’s call it yourpassword), we can continue.

Let’s write a little program Get.java that fetches a URL and tells us whether we got an error with the SSL connection:

import java.net.URL;
public class Get
{
   public static void main( String[] args ) throws Exception
   {
       try
       {
           new URL( args[0] ).openConnection().getInputStream();
           System.out.println( "Succeeded." );
       }
       catch( javax.net.ssl.SSLHandshakeException e )
       {
           System.out.println( "SSL exception." );
       }
   }
}

Compile this with:

javac Get.java

And run it with:

$ java Get https://google.com
Succeeded.

This should succeed, because Java knows it can trust the benevolent Google deity, as we all do.

Now try it against your server with a self-signed (or otherwise untrusted) certificate and you should see an error:

$ java Get https://selfsigned.example.com
SSL exception.

And now for the answer you were waiting for. You don’t need to use keytool. Repeat: you don’t need to use keytool. To run Java telling it to trust your server, just do this:

$ java \
    -Djavax.net.ssl.trustStore=/path/to/trust.jks \
    -Djavax.net.ssl.trustStorePassword=yourpassword \
    Get https://selfsigned.example.com
Succeeded.

That’s it.

One thought on “Java HTTPS to a server with a self-signed certificate”

  1. I was trying to import the public cert of selfsigned into existing java cacerts keystore (which is default used by the java), but it didn’t until I did above. My understanding is all it needs is to trust the cert that I did by importing.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.