This document describes how to create and install an SSL certificate on a Tomcat server.

Tomcat uses a Java KeyStore (JKS) repository to hold all of the security certificates and their corresponding private keys used for SSL encryption. This requires the use of the keytool utility that comes with the Java Development Kit (JDK) or the Java Runtime Environment (JRE).

Two things to understand:

  • The alias is simply a “label” used by Java to identify a specific certificate in the keystore (a keystore can hold multiple certificates). It has nothing to do with the server name, or the domain name of the Tomcat service. A lot of examples show “tomcat” as the alias when creating the keystore, but it really doesn’t matter what you call it. Just remember when you do use it, you stick with it.
  • The common name (CN) is an attribute of the SSL certificate. Your browser will usually complain if the CN of the certificate and the domain in the URI do not match (but since you’re using a self-signed certificate, your browser will probably complain anyway). HOWEVER, when generating the certificate, the keytool will ask for “your first and last name” when asking for the CN, so keep that in mind. The rest of the attributes are not really that important.
In this document, we are going to go over creating a self-signed certificate and then an actual signed certificate from a Certificate Authority (CA).

Creating a Self-Signed Certificate

Why create a self-signed certificate?

  • It allows you to learn to create a keystore and certificate, which is good practice for getting an actual SSL certificate provided by a Certificate Authority.
  • It allows you to use a certificate right away and make sure it works successfully.
  • It's free.
How to get started creating your self-signed certificate:

1. Locate the keytool application. This can be found within the bin directory of your Java JDK or JRE. For example:

/usr/local/Java/bin/keytool

2. Create the keystore and the certificate.

Use the following syntax to build your keystore and your self-signed certificate:

  • The path to the keytool
  • The -genkey flag to indicate you want to generate the keystore
  • The -keystore flag and the path to where you want your keystore located
  • The -alias flag and the alias you want to use for the keystore
  • The -keyalg flag and the algorithm type you want to use for the keystore
  • The -keysize flag and the value of the certificate encryption size
  • The -validity flag and the number of days you want the certificate to be valid for
  • The -ext flag to generate the SAN entry that is required by some modern browsers
For example:

/usr/local/Java/bin/keytool 
-genkey
-keystore /labkey/apps/lib/keystore.jks
-alias tomcat
-keyalg RSA
-keysize 4096
-validity 720
-ext SAN=dns:localhost,ip:127.0.0.1

3. The string will then create a series of prompts, asking for you to supply a password for the keystore and create what is known as a Certificate Server Request (CSR):

  • The keystore password and to confirm the password.
  • The domain you want your SSL certificate made for.
NOTE: This prompt will literally ask the question “What is your first and last name? [Unknown]:” This is NOT your first and last name. This should be the domain you want to make the SSL certificate for. Since this section is about creating a self-signed certificate, please enter localhost as the domain and press Enter.
  • The name of your Organizational Unit. This is optional, but most will put down the name of the department the certificate is being used for or the department the certificate is being requested by.
  • The name of your Organization. This is also optional, but most will put in the name of their company.
  • The name of your city. This is also optional, but most will put in the city the company or department is located in.
  • The name of your state/province. This is also optional, but if you do choose to enter in this information DO NOT abbreviate the information. If you choose to enter data here, you must spell out the state/province. For example: California is acceptable, but not CA.
  • The two-letter country code. This is optional, but if you’ve already entered the rest above, you should enter the two-letter code. For example: US for United States, UK for the United Kingdom.
  • Confirmation that the information you entered is correct.
  • A final prompt to enter the certificate, but just press Enter to use the same one as the Keystore from earlier.
The steps above will create the new keystore and add the new self-signed certificate to the keystore.

4. Configure the server.xml file to use the new keystore & self-signed certificate.

Now that the keystore and certificate are ready, you now will need to configure the server.xml file to use them.

  • Access the server.xml located in the Tomcat directory, under the conf directory.
  • Activate the HTTPS-Connector listed in the server.xml file. It should look something like the example below. Be sure to change the keyAlias, keystoreFile, and keystorePass to the ones you created earlier:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keyAlias="tomcat" keystoreFile="/labkey/apps/lib/keystore.jks"
keystorePass="THEPASSWORD" />

5. Restart Tomcat and try to connect to your local server as https://localhost and see if you are able to connect to it via HTTPS. If this works, then you should be able to also connect to your LabKey instance as HTTPS as well.

Creating a Self-Signed Certificate with Better Security on OpenJDK 11 (optional)

If you'd like to create a self-signed certificate with better security on OpenJDK 11, follow these steps instead of the steps in "Creating a Self-Signed Certificate" above.

1. Ensure you are running the keytool from your OpenJDK 11 installation, and not other places (like the Oracle JDK). Inspect your $JAVA_HOME (Mac) or %JAVA_HOME (Windows) (or the directory you're running keytool from) and ensure that the root is OpenJDK 11. For example, on my Mac the local directory is "/Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home/bin".

2. Create the keystore and the certificate. Here are some example commands you can run to do this:

Note: Be sure to change <your password> in these commands to a password of your choosing and add a <keystore location> and <certificate location> that you will remember (likely the same location).

$JAVA_HOME/bin/keytool -genkeypair -alias my_selfsigned -keyalg RSA -keysize 4096 -validity 720 -keystore <keystore location>/my_selfsigned.p12 -storepass <your password> -keypass <your password> -ext SAN=dns:localhost,ip:127.0.0.1
$JAVA_HOME/bin/keytool -exportcert -alias my_selfsigned -file <certificate location>/my_selfsigned.cer -keystore <keystore location>/my_selfsigned.p12 -storepass <your password>

3. You will need to answer a series of prompts to create the Certificate Server Request (CSR), just like in the section #3 above (under "Creating a Self-Signed Certificate"). Please see that section #3 above for details.

4. Like the section #4 above, you will need to configure the server.xml file to use the new keystore & self-signed certificate. In the server.xml file located in the Tomcat directory (under the conf directory), you should add the following connector:

Note: Be sure to change the certificateKeyAlias, certificateKeystoreFile, and certificateKeystorePassword to the ones you used earlier (especially the password).

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200" SSLEnabled="true" scheme="https" secure="true"
>
<SSLHostConfig
sslProtocol="TLSv1.2" protocols="TLSv1.2"
ciphers="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"

honorCipherOrder="true"
>
<Certificate
certificateKeyAlias="my_selfsigned"
certificateKeystoreFile="$/labkey/apps/lib/my_selfsigned.p12"
certificateKeystorePassword="password_here"
certificateKeystoreType="PKCS12"
type="RSA"/>
</SSLHostConfig>
</Connector>

5. (optional, for Mac) For some uses (like running LabKey automated tests in HTTPS) you'll need to add the certificate manually to your OS and to Java.

    • Find your my_selfsigned.cer file from step #2, go to Applications -> Utilities -> Keychain Access, and drag the file there.
    • Now we need to make this certificate trusted. Go to the Certificates line in the Category section in the lower-left corner of this window, find the "localhost" entry, and double-click it. Then expand the Trust section, and change "When using this certificate" to "Always Trust". Click the close button in the upper left and type your password to finish this operation.
    • Import the same my_selfsigned.cer file into your Java cacerts (which assumes you have not changed your Java's default keystore password of "changeit") by executing this command on the command line:
$JAVA_HOME/bin/keytool -importcert -cacerts -alias my_selfsigned -file <certificate location>/my_selfsigned.cer -storepass changeit
    • If you're trying to run LabKey's automated tests, don't forget to edit, in the test.properties file, labkey.port to "8443" and labkey.server to "https://localhost".
6. (optional, for Windows) For some uses (like running LabKey automated tests in HTTPS) you'll need to add the certificate manually to your OS and to Java. To add the certificate to the Trusted Root Certificate Authorities and Trusted Publishers
  • Go to Windows command line and run the command, certmgr. This will open certificate manager for current user. Perform the following in certificate manager.
    • Right click on Personal/Certificates. Select, All Tasks > Import. This should open Certificate Import Wizard.
    • Current User should be selected. Next.
    • Enter the path to the certificate you created, <certificate location>/my_selfsigned.cer. Next.
    • Place all certificates in the following store, should be selected. Certificate store should be Personal.
    • Review and click Finish.
    • You should now see your certificate under Personal/Certificates.
    • Right click and Copy the certificate.
    • Paste certificate into Trusted Root Certification Authorities/Certificates
    • Paste certificate into Trusted Publishers/Certificates
    • Close certmgr.
    • If you're trying to run LabKey's automated tests, don't forget to edit, in the test.properties file, labkey.port to "8443" and labkey.server to "https://localhost".
  • Execute the following to add your certificate to Java cacerts.
"%JAVA_HOME%/bin/keytool" -importcert -cacerts -alias my_selfsigned -file <certificate location>/my_selfsigned.cer -storepass changeit

Note: Windows may not pick up the certificate right away. A reboot should pick up the new certificate.

7. Restart Tomcat and try to connect to your local server as https://localhost:8443/labkey and see if you are able to connect to it via HTTPS. If you did everything correctly, you should see a grey padlock to the left of the URL, and not red "https" with a line through it.

Configuring LabKey Server to use HTTPS

Be sure to change the LabKey Server settings in your admin console to support HTTPS better. Go to the admin console, go to Admin Console Links -> Configuration -> Site Settings, and change the following values (which assume localhost as your server and port 8443, like the example above in "Creating a Self-Signed Certificate with Better Security on OpenJDK 11"):

In particular, you'll want to do that second item ("Require SSL connections"), because you will no longer be able to sign in to LabKey properly via HTTP.

Creating a Real Certificate

Once you’ve successfully created your own self-signed certificate, the steps to requesting and adding an actual certificate will be significantly easier.

To create your actual certificate, do the following:

1. Create the new keystore

  • Repeat step 2 in the self-signed section, but this time enter the domain you want the SSL certificate to be assigned to. For example, if your domain was “mylab.sciencelab.com”, you can run the following:
/usr/local/Java/bin/keytool 
-genkey
-keystore /labkey/apps/lib/mylab.sciencelab.com.jks
-alias tomcat
-keyalg RSA
-keysize 4096

This would create a new dedicated keystore for your new domain. You can opt to use the existing keystore you created, but I prefer to keep that self-signed one separate from the legitimate one.

  • Go through the same steps as step 3 in the self-signed section, enter in your actual domain name when prompted for “What is your first and last name? [Unknown]:”. Everything else stays the same as before.
2. Create the Certificate Signing Request (CSR): Now that the keystore is made, you can now make the CSR that you will then send to the certificate provider (such as GoDaddy.com, Comodo.com, or SSLShopper.com)

Run the following command:

/usr/local/Java/bin/keytool 
-certreq
-alias tomcat
-keyalg RSA
-keysize 4096
-keystore /labkey/apps/lib/mylab.sciencelab.com.jks
-file /labkey/apps/lib/mylab.sciencelab.com.csr

(Note: You can technically give the CSR any name, but I prefer to use the name of the domain and the extension .csr to keep things orderly)

When you run through the CSR, you’ll be prompted similarly like you were when you created the keystore. Enter in all the same respective values.

Once you are finished, open the .csr file using your favorite plain-text editor. You will see a long hash contained within two lines. This is the CSR that you will provide to the certificate provider to order your SSL certificate.

3. Applying your SSL certificate:

Once you receive the SSL certificate from your certificate provider, they may provide you with a few certificates, either 2 certificates (a Root certificate and the certificate for your domain) or 3 certificates (a Root certificate, an intermediate certificate, and the certificate for your domain). Sometimes, you may just get one certificate that has all of those certificates combined. Your certificate provider will provide you with an explanation on what they issued you and instructions on how to use them as well if you are in doubt.

Place the certificate(s) you’ve received in the same directory as the keystore.

If you are provided with a root and/or an intermediate certificate, run the following command:

/usr/local/Java/bin/keytool 
-import
-alias root
-keystore /labkey/apps/lib/mylab.sciencelab.com.jks
-trustcacerts
-file /labkey/apps/lib/certificate_file_name.crt

Take note that the alias is “root” and not the alias you’re using from before. This is intentional. Do not use the alias you used for the CSR or the keystore for this.

Otherwise, if you only received a single certificate, run the following:

/usr/local/Java/bin/keytool 
-import
-alias tomcat
-keystore /labkey/apps/lib/mylab.sciencelab.com.jks
-file /labkey/apps/lib/certificate_file_name.crt

Once the certificate is loaded into the keystore, the final step is to reconfigure the SSL connector in the server.xml file.

4. Update your server.xml with the new SSL certificate info:

Repeat step 4 from the self-signed section. Update the connector to point to your new keystore. For example:

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keyAlias="tomcat" keystoreFile="/labkey/apps/lib/mylab.sciencelab.com.jks"
keystorePass="THEPASSWORD" />

Once this is done, restart Tomcat for the changes to take effect.

Note: We recommend using the server.xml examples we provider here within our GitHub repository: https://github.com/LabKey/samples/tree/master/ops/config-examples

Creating Special Wildcard and Subject Alternative Names (SAN) Certificates:

  • Sometimes you may need to create a certificate that covers multiple domains. There are two types of additional certificates that can be created:
    • Wildcard certificates that would cover any subdomain under the main one.
    • Subject Alternative Name certificates (SAN) that would cover multiple domains.
  • To create a wildcard certificate, you would simply use an asterisk in lieu of a subdomain when creating your keystore and CSR. So the example of mylabs.sciencelab.com, you would use *.sciencelab.com instead and then when requesting your certificate from the provider, you would specifically indicate that you want a wildcard certificate.
  • To create a SAN certificate, you would insert the additional domains and IPs you wish the certificate to apply to when you run the keytool command.
For example:

/usr/local/Java/bin/keytool 
-genkey
-alias tomcat
-keyalg RSA
-keysize 4096
-keystore /labkey/apps/lib/mylab.sciencelab.com.jks
-file /labkey/apps/lib/mylab.sciencelab.com.csr
-ext SAN=dns:mylab.sciencelab.com,dns:mylab.ultimatescience.net,dns:mylab.researcherscience.org,ip:33.33.33.33

Related Topics

Discussion

Was this content helpful?

Log in or register an account to provide feedback


previousnext
 
expand all collapse all