This topic describes how to create and install an SSL/TLS certificate on a Tomcat server. First we cover the process for creating a self-signed certificate and then an actual signed certificate from a Certificate Authority (CA).

Tomcat uses a Java KeyStore (JKS) repository to hold all of the security certificates and their corresponding private keys. This requires the use of the keytool utility that comes with the Java Development Kit (JDK) or the Java Runtime Environment (JRE). Review this topic for current JDK version recommendations: Supported Technologies

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/TLS 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.

Create 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/TLS 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:

Step 1. Locate the keytool application within your JDK installation. Confirm that your <JAVA_HOME> environment variable points to the current supported version of the JDK and not to another JDK or JRE you may have installed previously.

The keytool will be in the bin directory. For example (where ## is the specific version number):

/usr/local/labkey/apps/Java/jdk-##.jdk/Contents/Home/bin/keytool

Step 2. Create the keystore and the certificate. When you use the following commands, be sure to change <your password> to a password of your choosing and add a <keystore location> and <certificate location> that you will remember, likely the same location.

Use the following syntax to build your keystore and your self-signed certificate. Some examples follow.

  • The path to the keytool
  • The -genkeypair flag to indicate you are creating a key pair
  • The -exportcert flag to generate the certificate
  • 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 for which you want the certificate to be valid
  • The -keystore flag and the path to where you want your keystore located
  • The -file flag and the path where you want the certificate located
  • The -storepass flag and your password
  • The -keypass flag and your password
  • The -ext flag to generate the SAN entry that is required by some modern browsers
For example:
$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>

Step 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/TLS 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/TLS 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.

Step 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. 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>

Step 5. (Optional) You can create a working certificate without this step, but for some uses (like running LabKey automated tests in HTTPS) you'll need to add the certificate manually to your OS and to Java so that they know to trust it. To add the certificate to the Trusted Root Certificate Authorities and Trusted Publishers, follow the instructions for your operating system below.

  • If you're trying to run LabKey's automated tests, edit the test.properties file to change labkey.port to "8443" and labkey.server to "https://localhost".
For OSX:
  • 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
For Windows:
  • 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. Click Next.
    • Enter the path to the certificate you created, <certificate location>/my_selfsigned.cer. Click Next.
    • Select "Place all certificates in the following store". 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 the certificate into Trusted Root Certification Authorities/Certificates.
    • Paste the certificate into Trusted Publishers/Certificates.
    • Close certmgr.
    • Before running LabKey automated tests, edit the test.properties file: change 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
Windows may not pick up the certificate right away. A reboot should pick up the new certificate.

Step 6: 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.

Configure LabKey Server to use HTTPS

Be sure to change the LabKey Server settings in your admin console to support HTTPS better. Go to (Admin) > Site > Admin Console > Settings > Configuration > Site Settings, and change the following values (which assume localhost as your server and port 8443):

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.

Create 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/TLS 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/TLS certificate.

3. Applying your SSL/TLS certificate:

Once you receive the SSL/TLS 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/TLS connector in the server.xml file.

4. Update your server.xml with the new SSL/TLS 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/main/ops/config-examples

Create 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

Was this content helpful?

Log in or register an account to provide feedback


previousnext
 
expand allcollapse all