Setting up Tomcat to use an existing OpenSSL certificate

Updated . Posted . Visible to the public.

This is for those who already own an SSL certificate (e.g. using it in the Apache HTTP Server) and need to feed it to a Tomcat application. The main issue is that you need to convert your OpenSSL certificate for Java to use it in its keystore.

Create a keystore

This is the place where the application usually gets its keys from. The keytool Show archive.org snapshot is able to read certificate files but does not understand private key files which you need to use your certificate.

For me the only way to achieve this was using a small Java application created by AgentBob Show archive.org snapshot and also attached to this note. You do want to read through such code first and not mindlessly use it on your private keys.

  1. Convert your private key and certificate from the PEM format into DER (PKCS8, not PKCS12):

    openssl pkcs8 -topk8 -nocrypt -in myhost.key -inform PEM -out myhost.key.der -outform DER
    openssl x509 -in myhost.crt -inform PEM -out myhost.crt.der -outform DER
    
  2. Modify the ImportKey.java to set a passphrase for the keystore and an alias to access your certificate.

  3. Compile it into a class file:

    javac ImportKey.java
    
  4. Run it to import your key and certificate:

    java ImportKey myhost.key.der myhost.crt.der
    

The application then creates a file keystore.ImportKey which holds a combination of your certificate and private key that you can put into your application directory, e.g. under conf/keystore.

You do not need to add any intermediate certificate authorities to the keystore.

Set up your server.xml

You are now ready to use your certificate. Modify your server.xml inside the application directory and add a Connector entry like this:

<Connector port="8443" maxHttpHeaderSize="8192"
           maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
           enableLookups="false" disableUploadTimeout="true"
           acceptCount="100" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS" SSLEnabled="true"
           URIEncoding="UTF-8"
           keystorePass="secret123456" keystoreFile="conf/keystore"
           keyAlias="private_key" />
  • Providing the keystoreFile and keystorePass (the password you chose above) tells the application how to access the keystore.
    If you encountered the "java.io.IOException: jsse.invalid_ssl_conf" exception before, this is most likely the answer to it.

  • Setting the keyAlias (you put it into the ImportKey.java) hints which key to use.
    If you got an exception like "java.io.IOException: Alias name foobar does not identify a key entry" you were providing an existing name but only a certificate without a private key.

  • You can also modify those settings later by using the corresponding keytool commands.

Now you should be able to restart your application and access it via SSL on port 8443. If it does not come up (maybe only listening on non-SSL ports) check the logs for any of the above exceptions.

Important: Remove any world and group permissions on the server.xml to keep your passphrase hidden from other users/applications on the server. You may want to chmod your keystore, too.

chmod g-rwx,o-rwx server.xml keystore
Arne Hartherz
Last edit
Arne Hartherz
Attachments
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2011-01-24 17:03)