18

I have a Java servlet currently running on Tomcat 7 (Windows) and it connects to a SQL Server database. I now need to encrypt this connection and I have a public Key SSL certificate in a keystore. But apparently I have to configure a system property for a "Truststore" and have the truststore set to the keystore.

The keystore location is C:\SSLKeys\appkeystore.key and from what I have found I have to set the Truststore up with the following;

Djavax.net.ssl.trustStore=C:\SSLKeys\appkeystore.key
Djavax.net.ssl.trustStorePassword=appkeystorePassword

But how do I set these please? I have tried it in the command line but that doesn't seem to work. I don't want to hard code these in the Java as I need them to be configurable.

Can these be set in the Catalina.bat file in Tomcat? If so where in the file do I put the command?

StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
AJF
  • 1,801
  • 4
  • 27
  • 54

4 Answers4

27

I think I may have found how, or at least one way of doing this. Someone please tell me if there is a better way of processing this. In the Tomcat\bin folder, where the catalina.bat file is I created a setenv.bat file and in there I declared the two Java option properties for;

set JAVA_OPTS="-Djavax.net.ssl.trustStore=C:\path\to\keystore.key" "-Djavax.net.ssl.trustStorePassword=************"

Apparently when Tomcat is started it initiates the catalina.bat file and the catalina.bat file determines if a setenv.bat file exists and if so runs this file to set the Java options.

Again someone please correct me if I am wrong and advise of any better way of doing this. Although apparently where Tomcat is set up as a Windows service the options above are input through the tomcatXw.exe to initiate the Tomcat console and the Java tab is selected.

yoozer8
  • 7,361
  • 7
  • 58
  • 93
AJF
  • 1,801
  • 4
  • 27
  • 54
  • But in this case, trustStorePassword will be visible when you do a ps -ef | grep 'javax.net.ssl'. Ideally, ssl details should be put in a separate properties file which should be referred in catalina.sh or setenv.sh. – Larsen Mar 11 '20 at 08:21
  • 1
    He's using set so there's no PS in windows :D – Andrew Carr Dec 01 '20 at 20:46
  • For me in Windows, I have to create setenv.bat and enter set JAVA_OPTS=-Djavax.net.ssl.trustStore=C:\path\to\keystore.key . I had to remove all quotes for it to work – likeGreen Feb 11 '22 at 19:49
14

Incase anybody else is having this question, here is what I did:
1. Navigate to \tomcatDirectory\bin\
2. Edit the catalina.sh/bat depending on you machine.
3. Add these properties to the JAVA_OPTS property

JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=$CATALINA_HOME/certificates/truststore.ks -Djavax.net.ssl.trustStorePassword=truststorePassword -server"

This will essentially tell tomcat to use the specified truststore instead of the default cacerts truststore which tomcat loads if it does not find any truststore specified in the system properties.

Also, I have noticed that it is possible to define the truststore in tomcat's main configuration file server.xml. All you have to do is set these properties in the connector property.

<Connector port="8443" maxThreads="500"
           server="Apache"
           scheme="https" secure="true" SSLEnabled="true" acceptCount="500"
           keystoreFile="/apps/content/certificates/keystore.ks" keystorePass="keystorepass"
           truststoreFile="/apps/content/certificates/truststore.ks" truststorePass="truststorePassword"/>

Try it out, Hope it helps!

HeCodes
  • 181
  • 2
  • 9
  • 6
    The purposes of the key/truststore settings in `JAVA_OPTS` and in the `Connector` are different. – Bruno Jun 30 '15 at 15:46
  • Oh! okay, I have never really tried the second approach so I wouldn't really know about that. It was just something I noticed while messing around with tomcat configurations. Thanks for the correction by the way! – HeCodes Jun 30 '15 at 15:57
  • 11
    Basically, the truststore parameters in `Connector` are for setting which client certificates you want to trust. The `javax.net.ssl.*` settings in `JAVA_OPTS` affect the default SSL context (typically for connection made from within the servlets, where they act as clients, for example). – Bruno Jun 30 '15 at 15:59
  • 2
    Editing the catalina.sh file is not recommended. In fact the file even says specifically how to do it: `Do not set the variables in this script [catalina.sh]. Instead put them into a script setenv.sh in CATALINA_BASE/bin to keep your customizations separate.` – mlathe Nov 01 '16 at 22:21
  • Which java tomcat will use by default ? – Diego Ramos Feb 19 '21 at 21:59
  • I was using TeamCity on Windows and editing the Catalina.bat in \bin\ to add the parameters as you said got rid of this error. The cacerts file is in \jre\lib\security. Then I needed to add my org's cert to the cacerts file which was done by following this post: https://stackoverflow.com/questions/21076179/pkix-path-building-failed-and-unable-to-find-valid-certification-path-to-requ – Khoward Sep 07 '21 at 21:21
3

The recommended answer only works for Tomcat deployed in Windows, I found that the below works for me in Linux server:

TOMDOGEDIRECTORY/bin/setenv.sh [You need to create this file yourself]

JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/opt/meh_tuststove.jks" 
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=muchsecure" 
export JAVA_OPTS
Ng Sek Long
  • 4,233
  • 2
  • 31
  • 38
  • 3
    Now it is better CATALINA_OPTS instead – user1156544 Aug 09 '18 at 13:35
  • do i really need to mention the password ? I mean javax.net.ssl.trustStorePassword . While trying in ide ( eclipse or IntelliJ ) i can use it just by -Djavax.net.ssl.trustStore . please help – JustTry Sep 22 '21 at 22:33
0

You need to change server.xml file for this. You can find it in conf/ directory.

First uncomment these lines:

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

and then change it something like this

<Connector SSLEnabled           ="true"
           acceptCount          ="100"
           clientAuth           ="false"
           disableUploadTimeout ="true"
           enableLookups        ="false"
           maxThreads           ="25"
           port                 ="8443"
           keystoreFile         ="C:\SSLKeys\appkeystore.key"
           keystorePass         ="password"
           protocol             ="org.apache.coyote.http11.Http11NioProtocol"
           scheme               ="https"
           secure               ="true"
           sslProtocol          ="TLS"
/>
StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
celezar
  • 442
  • 3
  • 9
  • Thanks celezar. But I already have the "keystoreFile" parameter set up in the server.xml connector tag. So this hasn't made any difference. From what I have found so far it appears I have to declare some sort of Java system property to create a "Truststore" using a command like Djavax.net.ssl.trustStore="C:\SSLKeys\appkeystore.key" but there is no exact tutorial on how to do this. I tried it in the command line but that didn't work. – AJF Feb 17 '14 at 16:38
  • 1
    Your answer is about configuring TLS enabled *connector*, which accepts *incoming* connections, but the question is about trusting certificates of *outgoing* connections, i.e. when servers connects to database—totally different thing – Cromax Sep 21 '20 at 15:52