You are here

Encrypting passwords in Tomcat


Apache Tomcat is by far the most popular (open source) web server and Java servlet container. It has been around for a long time and – at the time of writing this post – has reached version 7.0.29. As Apache rightfully claims on its web site, Tomcat powers numerous large-scale, mission-critical web applications across a diverse range of industries and organizations. Therefore, one might imagine that such a widely used server would out-of-the-box already prove to be very secure .


However, alot of weaknesses in Apache Tomcat stem from incorrect or inappropriate configuration – as is the case not only for Tomcat but for the majority of software products, I would imagine. The OWASP organization has written up a nice document with a lot of best practices and recommendations on how to make Tomcat more secure than the default out-of-the-box installation.


The OWASP document rightfully states that best practices advice us never to store clear text passwords, but that in the case of the server.xml it is very difficult to avoid. In this post, I will try to look into ways to avoid storing clear text password in Tomcat’s files that hopefully will make it less difficult to avoid.


Encrypt the admin’s password


Tomcat comes with a nice little app called the Web Application Manager, which makes it easy to deploy a new war-file. To be able to use the application you have to add an account with the role of “manager-gui”. This is done by adding the following two lines to the conftomcat-users.xml file:



As you can clearly see, the password is stored in plain text, which is something we would always like to avoid, especially in a production environment. Also, in real life of course, you would never use admin as the username or password ;).


Fortunately, although it apparently isn’t widely known, Tomcat comes with a script that  allows us to encrypt passwords. This script is called digest.bat on Windows or on Linux and can be found in the bin directory. With this we can specify the encryption algorithm that we want to use – here we’re using SHA-256 – and we enter the text we want to encrypt:



We can now replace the plain text password in the conftomcat-users.xml file by the AES digest.


But we’re still not quite there yet. We some how have to tell Tomcat that we’ve encrypted the password. So open the file confserver.xml in your editor and locate the following lines of code:



Add the attribute digest=”sha-256″ so you end up with the following:



Encrypting database passwords


It is well documented how we can configure a JDBC DataSource in Tomcat, and use it in a web application. Within our application we add a resource-ref to our web.xml, like so:



Next, we have to download and install the appropriate JDBC driver and copy it to Tomcats lib folder. Then we have to edit the confcontext.xml file and link our resource-ref to a data source by adding the following:



Finally, edit confserver.xml and add the following lines to the GlobalNamingResources (in this example we’re using Microsoft SQL Server):



That’s it. We’ve configured a DataSource for use in our applications. But, oh dear, as you can clearly see, the database credentials are stored in plain text. And this time we don’t have the aid of a digest.bat script.


Write your own DataSourceFactory


The only thing we can do now, is write our own DataSource that uses encrypted passwords. Of course, we’re not going to write a complete implementation ourselves. Instead, for this example, we are going to rely on the default connection pool that comes with Tomcat, called Tomcat JDBC Connection Pool, and we will create a class that will extend org.apache.tomcat.jdbc.pool.DataSourceFactory.


First of all, create a new Java project and add the tomcat-jdbc library to your classpath. If you’re using maven, simply add the following dependency:



Next, we have to write a class called Encryptor that can be used to encrypt and decrypt our passwords. For our example we are going to use the use the AES algorythm. I’m not going to explain the details about AES or encryption since there are already a lot of good articles on the web written by far more capable people than me.


So what we have here is nothing more than some code that can encrypt and decrypt text using the AES algorythm. What is important to note is that I’ve added a main method which will enable us later on to encrypt our password from the commandline in order to copy and paste it into our Tomcat configuration file.


Now what we’re actually most interested in, is the following class that we are going to write. So add a new class called EncryptedDataSourceFactory and have it extend org.apache.tomcat.jdbc.pool.DataSourceFactory:


Basically, the only thing that EncryptedDataSourceFactory does, is decrypt the database password. All the heavy lifting is left to org.apache.tomcat.jdbc.pool.DataSourceFactory.


The project is finished. So, export your project into an executable JAR file, e.g. encryptedDS.jar, and copy it to the Tomcat lib directory.


Encrypt your database password by executing the following:



Replace the password in server.xml with the encrypted one. And, finally we have to tell Tomcat to use our custom DataSource factory. To do so, add an attribute factory, specifying our fully qualified class, to the Resource element. So what we’ve should end up with in server.xml is the following:


So at last, with a little bit of effort, we’ve managed to encrypt our database password. And if you want to, you could even go one step further and also encrypt the other attributes
such as the username or url by adding a few more lines of code to the EncryptedDataSourceFactory.createDataSource() method.