Nicolas Frankel is an IT consultant with 10 years experience in Java / JEE environments. He likes his job so much he writes technical articles on his blog and reviews technical books in his spare time. He also tries to find other geeks like him in universities, as a part-time lecturer. Nicolas is a DZone MVB and is not an employee of DZone and has posted 224 posts at DZone. You can read more from them at their website. View Full User Profile

SSL your Tomcat 7

07.03.2011
| 32732 views |
  • submit to reddit

One thing I’m doing very often and always searching on the Internet is how to obtain a self-signed SSL certificate and install it in both my client browsers and my local Tomcat.

Sure enough there are enough resources available online, but since it’s a bore to go looking for the right one (yes, some do not work), I figured let’s do it right once and document it so that it will always be there.

Create the keystore

Keystores are, guess what, files where your store your keys. In our case, we need to create one that will be used by both Tomcat and for the certificat generation.

The command-line is:

keytool -genkey -keyalg RSA -alias blog.frankel.ch -keystore keystore.jks -validity 999 -keysize 2048

The parameters are as follow:

Parameter Value Description
-genkey   Requests the keytool to generate a key. For all provided features, type keytool -help
-keyalg RSA Wanted algorithm. The specified algorithm must be made available by one of the registered cryptographic service providers
-keysize 2048 Key size
-validity 999 Validity in days
-alias blog.frankel.ch Entry in the keystore
-keystore keystore.jks Keystore. If the keystore doesn’t exist yet, it will be created and you’ll be prompted for a new password; otherwise, you’ll prompted for the current store’s password

Configure Tomcat

Tomcat’s SSL configuration is done in the ${TOMCAT_HOME}/conf/server.xml file. Locate the following snippet:

<!--
  <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS" />
    -->

Now, uncomment it and add the following attributes:

  • keystoreFile="/path/to/your/keystore.jks"
  • keystorePass="Your password"

Note: if the store only contains a single entry, fine; otherwise, you’ll need to configure the entry’s name with keyAlias="blog.frankel.ch"

Starting Tomcat and browsing to https://localhost:8443/ will show you Tomcat’s friendly face. Additionnaly, the logs will display:

28 june 2011 20:25:14 org.apache.coyote.AbstractProtocolHandler init
INFO: Initializing ProtocolHandler ["http-bio-8443"]

Export the certificate

The certificate is created from our previous entry in the keystore.

The command-line is:

keytool -export -alias blog.frankel.ch -file blog.frankel.ch.crt -keystore keystore.jks

Even simpler, we are challenged for the keystore’s password and that’s all. The newly created certificate is now available in the filesystem. We just have to distribute it to all browsers that will connect to Tomcat in order to bypass security warnings (since it’s a self-signed certificate).

Spread the word

The last step is to put the self-signed certificate in the list of trusted certificates in Firefox. For a quick and dirty way, import it in your own Firefox (Options -> Advanced -> Show certificates -> Import…) and distribute the %USER_HOME%"/Application Data/Mozilla/Firefox/Profiles/xzy.default/cert8.db file. It has to be copied to the %FIREFOX_HOME%/defaults/profile folder so that every single profile on the target machine is updated. Note that this way of doing will lose previously individually accepted certificates (in short, we’re overwriting the whole certificate database). For a more industrial process, look at the next section.

To go further:

 

From http://blog.frankel.ch/ssl-your-tomcat-7

Published at DZone with permission of Nicolas Frankel, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Lieven Doclo replied on Mon, 2011/07/04 - 6:18am

A great tool for managing keystores without having to use the keytool command line tool is Portecle (http://portecle.sourceforge.net).

Rusty Wright replied on Tue, 2011/07/05 - 5:21pm

I followed your instructions with apache tomcat 7.0.16 on Windows 7.  When I start tomcat I get the following error.  How do I generate the file it wants?

INFO: Initializing ProtocolHandler ["http-apr-8443"]
Jul 5, 2011 3:20:16 PM org.apache.coyote.AbstractProtocol init
SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-apr-8443"]
java.lang.Exception: Connector attribute SSLCertificateFile must be defined when using SSL with APR
        at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:469)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:490)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:364)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:910)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:781)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:572)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:595)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:262)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:430)
Jul 5, 2011 3:20:16 PM org.apache.catalina.core.StandardService initInternal
SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8443]]
org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:912)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:781)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:572)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:595)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:262)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:430)
Caused by: java.lang.Exception: Connector attribute SSLCertificateFile must be defined when using SSL with APR
        at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:469)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:490)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:364)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:910)
        ... 13 more
Jul 5, 2011 3:20:16 PM org.apache.coyote.AbstractProtocol init

 

 

Rusty Wright replied on Tue, 2011/07/05 - 5:32pm in response to: Rusty Wright

Figured it out; for me the command is

keytool -exportcert -rfc -alias objecteffects.com -file objecteffects.com.cert.pem -keystore keystore.jks

Rusty Wright replied on Tue, 2011/07/05 - 5:45pm in response to: Rusty Wright

Sorry, I take that back; now I'm getting this error:

 SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-apr-8443"]
java.lang.Exception: Unable to load certificate key C:/Program Files/Apache Software Foundation/apache-tomcat-7.0.16/conf/objecteffects.crt (error:0906D06C:PEM
routines:PEM_read_bio:no start line)
        at org.apache.tomcat.jni.SSLContext.setCertificate(Native Method)
        at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:513)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:490)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:364)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:910)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:781)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:572)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:595)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:262)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:430)
Jul 5, 2011 3:44:04 PM org.apache.catalina.core.StandardService initInternal
SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8443]]
org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:912)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:781)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:101)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:572)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:595)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:262)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:430)
Caused by: java.lang.Exception: Unable to load certificate key C:/Program Files/Apache Software Foundation/apache-tomcat-7.0.16/conf/objecteffects.crt (error:0906D06C:PEM routines:PEM_read_bio:no start line)
        at org.apache.tomcat.jni.SSLContext.setCertificate(Native Method)
        at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:513)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:490)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:364)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:910)
        ... 13 more

 

(I renamed the file to objecteffects.crt on disk and in the server.xml file.)

Nicolas Frankel replied on Wed, 2011/07/06 - 1:42am

Hi,

I think the root of the problem lies in that you're using the Apache Portable Runtime, and I'm not. I think you should look into this direction.

Rusty Wright replied on Wed, 2011/07/06 - 11:41pm in response to: Nicolas Frankel

Ok, thanks.

I just thought I'd point out that your procedure doesn't work for everyone, since you started your article with "I figured let’s do it right once and document it so that it will always be there."

So it sounds like you're using the "non-portable" runtime?  Are you on unix?  My tomcat installation is freshly unzipped and unmodified.

Nicolas Frankel replied on Thu, 2011/07/07 - 2:03am in response to: Rusty Wright

The APR is a native library that you may install during Tomcat installation. It does tie your Tomcat to your OS but "provide superior scalability and performance". This is a good thing to do for your production environment. In other environments, I don't see the point.

You can see more info on the Tomcat website.

Rusty Wright replied on Thu, 2011/07/07 - 11:45am in response to: Nicolas Frankel

Then it seems they are distributing the Windows version of Tomcat with APR installed and enabled.  I didn't do anything after unzipping it.  The file tcnative-1.dll is in my tomcat bin directory.

fan fanfree replied on Sun, 2011/10/16 - 10:08pm

I  commented out the APR listener.  server.xml line:27;it works fine in Windows OS

Sirikant Noori replied on Sun, 2012/01/15 - 11:48am

The new feature in Tomcat 7 is that you can have a different password for the keystore and the alias. In previous versions, we had to put the same password.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.