JBoss Datasource Password Encryption/Hashing

In my previous post on JBoss password encryption I showed how to encrypt passwords for services that make use of the Jboss microcontainer. These services are configured in files that end with the suffix *-jboss-beans.xml. As stated in that post JBoss has a tendency for inconsistency in its configuration files and service setup due to its migration away from the JMX Kernel to the Microcontainer and its historical use of custom XML files for some setups like data sources. All of these differences mean that password encryption or masking is not a simple one workflow fits all situation. This deals with JBoss 6. I have not started to look at JBoss 7 yet until it comes out of beta mode.

JBoss Data Source Password Masking

To encrypt a datasource password, rather than having it in plain text in your *-ds.xml file requires two steps:

  1. Create a JBoss security domain that can use hashed passwords,
  2. Configure the datasource to use the secruity domain created above instead of coding username and password parameters in the datasource.

1 Create a security domain

This involves two steps:

  1. Encrypting the password,
  2. Editing the login-config.xml to add the new security domain 

1.1 Encrypting the password

As a first step you need to generated the encrypted password. JBoss proivdes a class to do this for you and the encrypted password can be obtained by running:

java -cp `./bin/classpath.sh --server`  org.jboss.resource.security.SecureIdentityLoginModule mytopsecretpassword
 
This will output the encrypted password which in this case is "-3852e0ce37dafe85020b4074486e42c2008fba5553e14ea0" for "mytopsecretpassword". Since the encryption will always produce the same hash this is subject to a rainbow table attack so make sure you use a strong password!

1.2 Editing the login-config.xml

The easiest way to create a new security domain is to edit the <jboss-home>/server/<config>/conf/login-config.xml file. (It would be better if this was called the security-domains.xml file.). When creating a new security domain, which is wrapped in an <application-policy> tag, so many names for the same thing :(,  you need to select the most appropriate implementation for your domain. In this case we need to use the SecureIdentityLoginModule. The xml snippet below explains it a lot better:

<application-policy name="SecurePassword">
  <authentication>
    <login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">
          <module-option name="username">root</module-option>
          <module-option name="password">-3852e0ce37dafe85020b4074486e42c2008fba5553e14ea0</module-option>
       <module-option name="managedConnectionFactoryName">jboss.jca:name=MySqlDS,service=LocalTxCM</module-option>
    </login-module>
  </authentication>
</application-policy>

So you place the database username and password in the security domain "SecurePassword" using the SecureIdentityLoginModule. Save the file and you all done with creating the security domain. Make sure the file has the correct OS permissions as you don't want everyone to be able to read the file gaining access to the username and hashed password.

2 Configure the datasource to use the new security domain

Now remove the username and password that usually appear in the *-ds.xml file and add a reference to the new security domain. See below for a  MySQL example:

<datasources>
    <local-tx-datasource>
        <jndi-name>MySqlDS</jndi-name>
        <connection-url>jdbc:mysql://127.0.0.1:3660/mydatabase</connection-url>
        <driver-class>com.mysql.jdbc.Driver</driver-class>
        <min-pool-size>1</min-pool-size>
        <max-pool-size>20</max-pool-size>
 
        <!-- REPLACED WITH security-domain BELOW
        <user-name>root</user-name>
        <password>mytopsecretpassword</password>
        -->
 
        <security-domain>SecurePassword</security-domain>
     </local-tx-datasource>
</datasources>
 
Note that the jndi name must match that used in the "managedConnectionFactoryName" module-option in the security-domain configured above and the security-domain entry must match the name of the security domain as defined in step 1.2 above.
 
Now you can use a reference to the data source as per usual in your jboss-web.xml file for example. Note you will use a different security domain for user authentication for your application.