Configuring Tomcat SSL/TLS

Secure Sockets Layer (SSL) and the new Transport Layer Security (TLS), are cryptographic protocols designed to provide a secure communication between two computers. They use certificates and cryptography to authenticate the counterpart with whom they are communicating and to negotiate a session key. This session key is used to encrypt data between the endpoints. A consequence of using certificates, is that Certificate Authorities (CA) and a public key infrastructure are necessary to verify the relation between a certificate and its owner, as well as to generate, sign, and administer the validity of certificates. Due to this reason you have two options to configure SSL:

  • Self-signed Certificate: it's free because you create your own certificate.
  • CA Certificate: It cost money because you need to pay for it to a certification authority.

Tomcat currently operates only on JKS, PKCS11 or PKCS12 format keystores. The JKS format is Java's standard "Java KeyStore" format, and is the format created by the key tool command-line utility. This tool is included in the OpenJDK. The PKCS12 format is an Internet standard, and can be manipulated via (among other things) OpenSSL and Microsoft's Key-Manager.

Each entry in a key store is identified by an alias string. Whilst many key store implementations treat aliases in a case non sensitive manner, case sensitive implementations are available. The PKCS11 specification, for example, requires that aliases are case sensitive. To avoid issues related to the case sensitivity of aliases, it is not recommended to use aliases that differ only in case.

Self-signed Certificate

Create the Certificate Key store

$ keytool -genkey -alias tomcat -keyalg RSA -keystore self-signed.jks

Enter keystore password: ********

Re-enter new password: ********
What is your first and last name? [Unknown]: Self-Signed Certificate
What is the name of your organizational unit? [Unknown]: System Management
What is the name of your organization? [Unknown]: OpenKM
What is the name of your City or Locality? [Unknown]: Palma de Mallorca
What is the name of your State or Province? [Unknown]: Islas Baleares
What is the two-letter country code for this unit? [Unknown]: ES
Is CN=Self-Signed Certificate, OU=System Management, O=OpenKM, L=Palma de Mallorca, ST=Islas Baleares, C=ES correct?
[no]: yes

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

The password changeit is the default password set into $TOMCAT_HOME/conf/server.xml file

Edit the Tomcat Configuration file

Enable the SSL connector:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
keystoreFile="${catalina.home}/sef-signed.jks" keystorePass="changeit" keyAlias="tomcat" />

Check configuration

Restart Tomcat service and check your OpenKM URL with https://YOUR_SERVER_IP:8443/OpenKM.

CA Certificate

Prepare the Certificate Key store

$ keytool -genkey -alias tomcat -keyalg RSA -keystore ca-signed.jks
Enter keystore password: ********
Re-enter new password: ********
What is your first and last name? [Unknown]: CA-Signed Certificate
What is the name of your organizational unit? [Unknown]: System Management
What is the name of your organization? [Unknown]: OpenKM
What is the name of your City or Locality? [Unknown]: Palma de Mallorca
What is the name of your State or Province? [Unknown]: Islas Baleares
What is the two-letter country code for this unit? [Unknown]: ES
Is CN=Self-Signed Certificate, OU=System Management, O=OpenKM, L=Palma de Mallorca, ST=Islas Baleares, C=ES correct?
[no]: yes
Enter key password for <tomcat>
(RETURN if same as keystore password):

The password changeit is the default password set into $TOMCAT_HOME/conf/server.xml file

Create the Certificate Signing Request

This step is different from the self-signed certificate because you need to send this information to the Certification Authority (CA) which need to validate and sign. Your chosen CA will send you back some files with the Root Certificate the Intermediate Certificates and the Primary Certificate (which is the certificate created for you).

$ keytool -certreq -keyalg RSA -alias tomcat -file ca-signed.csr -keystore ca-signed.jks

Install the Root Certificate

Every time you install a certificate to the key store you must enter the key store password that you chose when you generated it. Enter the following command to install the Root Certificate file:

$ keytool -import -trustcacerts -alias root -file RootCertFileName.crt -keystore ca-signed.jks

If you receive a message that says "Certificate already exists in system-wide CA keystore under alias <...> Do you still want to add it to your own keystore? [no]:", select Yes. If successful, you will see "Certificate was added to keystore".

Install the Intermediate Certificate

If your certificate authority provided an intermediate certificate file, you will need to install it here by typing the following command:

$ keytool -import -trustcacerts -alias intermediate -file IntermediateCertFileName.crt -keystore ca-signed.jks

If successful, you will see "Certificate was added to keystore".

Install the Primary Certificate

Type the following command to install the Primary certificate file (for your domain name):

$ keytool -import -trustcacerts -alias tomcat -file PrimaryCertFileName.crt -keystore ca-signed.jks

 The command  $ keytool -list -keystore ca-signed.jks -v shows all certificates imported.

Edit the Tomcat Configuration file

Enable the SSL connector:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
keystoreFile="${catalina.home}/ca-signed.jks" keystorePass="changeit" keyAlias="tomcat" />

Check configuration

Restart Tomcat service and check your OpenKM URL with https://YOUR_SERVER_IP:8443/OpenKM.

CA Certificate without preparing keystore

Sometimes the person who installs the certificate is not the same that made the request to obtain the certificate. In this case every step is similar to the previous one with the exception of the installation of the Primary Certificate.

In this case, when the primary certificate is installed, it is necesary to install the private RSA key too. To do it, apart from the primary certificate, the private RSA key must be given.

Obtain p12 certficate

Obtain p12 certificate from private key and primary certificate. This is the way that both keys are installed.

$ openssl pkcs12 -export -in PrimaryCertFileName.crt -inkey privateRSA.key > PrimaryCertFileName.p12

If successful, PrimaryCertFileName.p12 certificate will be created.

Install p12 Certificate

Type the following command to install the .p12 certificate file (for your domain name):

$ keytool -v -importkeystore -srckeystore PrimaryCertFileName.p12 -srcstoretype PKCS12 -destkeystore ca-signed.jks -deststoretype JKS

If successful, you will see "Certificate was added to keystore".

Change alias to Primary Certificate

Type the following command to install the .p12 certificate file (for your domain name):

$ keytool -changealias -keystore ca-signed.jks -alias 1 -destalias tomcat

Let's Encrypt

Let's Encrypt uses a client application which automates the certificate generation and renovation.

Client installation 

In Linux you can install the tool with these commands:

$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto

The first will install the required dependencies:

$ sudo ./certbot-auto

Certificate generation

Now it's time to generate a certificate. This is a sample command line used to generate only the certificate. For more info about usage and command line options, please visit https://certbot.eff.org/:

$ sudo ./certbot-auto certonly --standalone -m contact@mail-server.com -d sample-domain.com

This will create a directory structure where you can locate the certificate. This directory is protected so you need to switch to root to go into:

$ sudo su -

$ cd /etc/letsencrypt/live/sample-domain.com

As you can see there are seveal PEM files. Let's create a PKCS12 certificate from these files which will be used in Tomcat:

$ openssl pkcs12 -export -in cert.pem -inkey privkey.pem -CAfile chain.pem -caname root -name tomcat -out mycert.p12

Keep the password safe because it will be used later.

Tomcat configuration

Copy the generated file to TOMCAT_HOME and edit the $TOMCAT_HOME/conf/server.xml file to configure the new certificate:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
           keystoreFile="${catalina.home}/mycert.p12" keystorePass="changeit" keyAlias="tomcat" />

 Once Tomcat is started, the 8443 port will accept SSL connections. But remember these connection should only be done using the domain you used to generate the certificate, otherwise the browser will alert you about the site.

Other configuration

To redirect from non SSL port 8080 to SSL port 8443 edit the $TOMCAT_HOME/web.xml and append at the end:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>App_nmae</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>

    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

And restart Tomcat. 

Known issues

Windows uses a different protocol

In Window systems the protocol used in the Connector must be changed so the final configuration is:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
keystoreFile="${catalina.home}\ca-signed.jks" keystorePass="changeit" keyAlias="tomcat" />

ca-bundles certificates

Sometimes the certificates provider gives serveral certifcates in one file with .ca-bundle extension. Sometimes, when this bundle is imported as one file, only one of the certicates is imported. In is this case, the solution is to split the bundle in several files (once for each certificate).

To do it,  it is possible to edit the ca-bundle file, and each certificate is separated by:

-----BEGIN CERTIFICATE-----
        ....
....
-----END CERTIFICATE-----

Additional information

Are several ways to configure SSL in Tomcat for more information: