Friday, September 23, 2011

Get HTTPS to work for localhost on Tomcat

I needed to test how my app works with HTTPS locally, so I began going through the Tomcat 7 HOW-TO for setting up SSL. I got the basics out of it, but it didn't work locally and being a security n00b I really didn't understand what I was doing anyway. So I made a StackOverflow post, SSL in Tomcat 7 where EJP helped me get it to work. And thus I document it here so that I can repeat these steps in a year's time when I have completely forgotten what I did to get it working. I will note below what bits the Tomcat 7 HOW-TO didn't make clear with this marker: HOW-TO Note.

I am using Tomcat 7, Windows 7, JDK 6 - and I have %JAVA_HOME%\bin correctly set in my path.

1. Make a Key Pair

Use the Java keytool utility to generate a key pair (a public key and associated private key). If you haven't already created a keystore, this command will create one for you (by default in user home, so for Windows 7 the keystore created is the file C:\Users\USERNAME\.keystore).

The following shows what input I used for the command suggested by the HOW-TO: keytool -genkey -alias tomcat -keyalg RSA.

keytool -genkey -alias tomcat -keyalg RSA
Enter keystore password:  changeit
Re-enter new password: changeit
What is your first and last name?
  [Unknown]:  localhost
What is the name of your organizational unit?
  [Unknown]:  Dev
What is the name of your organization?
  [Unknown]:  MyBusiness
What is the name of your City or Locality?
  [Unknown]:  Melbourne
What is the name of your State or Province?
  [Unknown]:  Victoria
What is the two-letter country code for this unit?
  [Unknown]:  AU
Is CN=localhost, OU=Dev, O=MyBusiness, L=Melbourne, ST=Victoria, C=AU correct?
  [no]:  yes

Enter key password for         (RETURN if same as keystore password):

HOW-TO Note: in response to the question What is your first and last name? enter localhost, not your name!

If you have never run this command before, it will output a single file: C:\Users\USERNAME\.keystore. If you like, confirm that the aliased key pair has been made with a command such as keytool -list -alias tomcat, shown below.

keytool -list -alias tomcat
Enter keystore password: changeit
tomcat, 23/09/2011, PrivateKeyEntry,
Certificate fingerprint (SHA1): B2:B9:DB:B8:C3:9F:7D:2B:F8:82:A2:A2:C7:A2:9A:94:90:65:69:6E

2. Create Connector in server.xml

Open up the server.xml file for your Tomcat. I am running a Tomcat instance through Eclipse so for me the file is not the one stored in the Tomcat install directory (TOMCAT-INSTALL-DIR\conf\server.xml) but ECLIPSE-WORKSPACE\Servers\Tomcat v7.0 Server at localhost-config\server.xml. Look for the comment that includes the text Define a SSL HTTP/1.1 Connector on port 8443, and add the below XML after that comment.

<Connector port="8443" maxThreads="200"
        scheme="https" secure="true" SSLEnabled="true"
        keystoreFile="${user.home}/.keystore" keystorePass="changeit"
        clientAuth="false" sslProtocol="TLS"/>

Now restart Tomcat.

3. Load the App, Trust the Certificate

HOW-TO Note: the HOW-TO doesn't mention anything about this. Probably they didn't have localhost in mind, or maybe it's because I am not a trusted source of certificates.

  1. Load up your app in IE: https://localhost:8443/path/to/your/app (note the use of port 8443 - as per the Connector XML above).
  2. You will see an error page (There is a problem with this website's security certificate....). Click Continue to this website (not recommended).
  3. The address bar will be red and have the text "Certificate Error". Click on it. See the message: The security certificate presented by this website was not issued by a trusted certificate authority.
  4. Click View Certificates. See the below dialogue box.
  5. Click Install Certificate > Next
  6. Select Place all certificates in the following store > Browse > select Trusted Root Certificate Authorities > click OK.
  7. Click Next > click Finish. See this:
  8. Click Yes > see the message The import was successful > click OK > click OK.
  9. Re-load https://localhost:8443/path/to/your/app in IE and it should work without showing any certificate error!

Unresolved Issues

This isn't perfect though. There are two problems I haven't worked out yet.

It doesn't work if I install the certificate first. You can export the certificate like this.

keytool -export -alias tomcat -file tomcatcertfile.cer
Enter keystore password:  changeit
Certificate stored in file 

This will output a file in the same directory as the keystore file, by default C:\Users\USERNAME\tomcatcertfile.cer.

  1. Go Start Menu, type "Internet Options" > select Content tab > click Certificates.
  2. Select Trusted Root Certification Authorities tab.
  3. Click Import > click Next > enter File Name: C:\Users\USERNAME\tomcatcertfile.cer > click Next
  4. Click Next > click Finish > click OK > click close > click OK.

But after I did this, I still see a certificate error in IE.

It doesn't work in Chrome or Firefox - although in Firefox you can add an exception. In Chrome, I see the following error, which I have found no workaround for.

Pages that helped me with this post.