Sunday, June 27, 2010

SSL Configuration in Tomcat

Today, we are going to learn about how to setup SSL on your Tomcat so that you can access your application on HTTPS instead of HTTP and provide a secure interface to your clients. But before going into that, lets understand the basic difference between HTTP & HTTPS.

Introduction to HTTPS

HTTPS (HyperText Transfer Protocol Secure) combines HTTP protocol with SSL (Secure Sockets Layer) or TLS (Transport Layer Security) and offers a secure channel to browse the web so that you can trust the connection to send sensitive information like payment transactions details or your bank account details. The difference between the two clearly shows in the address bar where you can see https:// instead of http://. Also HTTPS uses port 443 as the default port, whereas HTTP uses port 80 as the default port for communication.

Using HTTPS, the two-way communication that occurs between your web browser and the host server is now secure and encrypted. This means that the data being sent is encrypted by one side, transmitted, then decrypted by the other side before processing.

When a web browser initially attempts to contact a web server over a secure connection, it is presented with a “certificate” (set of credentials), as a proof of the site is who what it claims to be. These certificates are signed (digitally verified) by certain authorities like VeriSign and typically purchased by the web server. Remember that you need to buy a certificate for each port on which you want a secure connection. For this blog entry, we will sign our own certificate and make other changes to Tomcat configuration so that it starts accepting connection on port 443 using HTTPS protocol.

But before we begin setting up SSL on Tomcat, its very important to iterate that this is valid only if you are using Tomcat as a stand-alone web server, the other possibility being Microsoft IIS or Apache Server serving as the main interface to the outside world and Tomcat is serving as the JSP/Servlet Container at the backend, communicating with one of these servers. In that case, you have to make SSL configuration changes in IIS or Apache, while Tomcat will continue to work normally sending cleartext responses (no encryption at Tomcat level).

Creating a Certificate

Fortunately, Java provides us with a utility (keytool) which can be used to create a self-signed certificate. This is not validated by any authority, hence not suitable for production use. But it can certainly be used for development purposes. So, lets  create a certificate from scratch for our application:

Type in the following command and enter details(credentials) about your organization that users of your site/application would see in the certificate given to them when they use it. The default password for Tomcat is “changeit” (all in lower-case). It would be asked when you type the following command to generate your self signed certificate:

>> keytool –genkey –alias –tomcat –keyalg RSA

Note, you must enter the password (as told above) and then all the credentials as shown below:

newCertificate

After doing this correctly, a .keystore file will be generated in your home folder (in the home folder of the user who did this). This is the certificate your tomcat would use and present to any user who visit the secure site.

Configuring Tomcat

Now, we make changes in Tomcat configuration to reflect this change. Tomcat uses 2 different implementations for SSL: Apache Portable Runtime (APR) implementation and JSSE Connector implementation, provided by default with JRE (Java Runtime). Most of the users (like me) do not have APR installed by default, so following steps are valid for JSSE implementation

We now open server.xml present in $CATALINA_HOME/conf. An example <Connector> element for SSL is included by default in most server.xml that comes with Tomcat. It looks something like this:

SSLconnector

All you have to do is to uncomment this connector and add to it the location of your certificate (.keystore) that we generated and the password we used to generate it. So finally the entry for the connector looks like:

NewConnector

Also, make sure that the Non-SSL Connector (the default one) which accepts connection on 8080, should have a redirectPort attribute set to 8443 or to the port that you specified for SSL Connection in the connector above. The entry looks like:NonSSLConnector

That’s all you need to do to make sure that Tomcat starts accepting secure connections on 8443 and redirects users who attempt to access a secure page with http to https. For more details regarding each attribute of the connector, you can refer Java HTTP Connector configuration reference.

Go ahead, try it out and feel the magic that Tomcat provides you. :-) Please post any bugs, queries and corrections as comments.