Tuesday, May 5, 2009

Encrypting Database passwords in JBoss Data Source File

If anybody uses JBoss as the application server, then they should be familiar with configuring JNDI data sources in JBoss. Generally to configure these JNDI based data sources they have to do the following:
  • Create a data source file under "deploy" folder with the name such as "oracle-ds.xml" or "hsqldb-ds.xml" etc.
  • In the above created file one can add the data source details as follows

<datasources>
<local-tx-datasource>
<jndi-name>ClusterSix</jndi-name>
<connection-url>jdbc:oracle:thin:@10.0.0.0:1521:SID</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>user</user-name>
<password>pwd</password>
<min-pool-size>2</min-pool-size>
<max-pool-size>5</max-pool-size>
<blocking-timeout-millis>60000</blocking-timeout-millis>
<idle-timeout-minutes>1
<valid-connection-checker-class-name>
org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>
</local-tx-datasource>
</datasources>


This is all you need and you have a JNDI associated with your DB. The problem with the above approach is the password of the DB is exposed to the outside world and hence it may be s security issue. Do you agree with me?

It would be nice if there is a way to encrypt the password and use it safely in the data soure file. Does JBoss supports such type of encrypted passwords? The answer is "YES" it supports.

Below is the process which tells how to use encrypted passwords in your data source files.

The SecureIdentityLoginModule from jboss-jca.jar can be used to encrypt database passwords rather than using clear text passwords in the datasource configuration. It uses a hard-coded password to encrypt the datasource password. You can encrypt the datasource password using the SecureIdentityLoginModule main method by passing in the cleartext password


Step 1: Encrypt your password:

  • cd into the root of your jboss server. ex: cd /usr/local/jboss-3.2.7
  • execute java -cp lib/jboss-jmx.jar:lib/jboss-common.jar:server/default/deploy/jboss-jca.sar:server/default/lib/jbosssx.jar org.jboss.resource.security.SecureIdentityLoginModule
  • The result will be your encrypted password such as 5dfc52b51bd35553df8592078de921bc

Step 2: Add the encrypted password to the data source file (oracle-ds.xml)

<datasources>
<local-tx-datasource>
<jndi-name>ClusterSix </jndi-name>
<connection-url>jdbc:oracle:thin:@10.0.0.0:1521:SID</connection-url>

<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<security-domain>EncryptClusterSixPassword</security-domain>
<min-pool-size>2</min-pool-size>
<max-pool-size>5</max-pool-size>
<blocking-timeout-millis>60000</blocking-timeout-millis>
<idle-timeout-minutes>11</IDLE-TIMEOUT-MINUTES>
<valid-connection-checker-class-name> org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>
</local-tx-datasource>
</datasources>

You can observe that the above Datasource configuration does not contain username and password tags as shown earlier, in place of these we could see a word "EncryptClusterSixPassword". Now where is this word came from and where did we mentioned the encrypted password generated earlier. From the third step you will get an idea what happened.

Step 3: Add an entry to login-config for each datasource:
Add the following for each datasource in login-config.xml. Make sure that the jboss.jca:name equals the data source defined in oracle-ds.xml. You will need one for each cluster.

<application-policy name="EncryptClusterSixPassword">
<authentication>
<login-module flag="required" code="org.jboss.resource.security.SecureIdentityLoginModule">
<module-option name="username">user1</MODULE-OPTION>
<module-option name="password">
-5dfc52b51bd35553df8592078de921bc
</MODULE-OPTION>
<module-option name="managedConnectionFactoryName">
jboss.jca:name=ClusterSix,service=LocalTxCM
</MODULE-OPTION>
</LOGIN-MODULE>
</authentication>
</APPLICATION-POLICY>


Note that login-config.xml file name should be as it is and it should be placed under /jboss/server/conf folder.

That is all, you are done and no password is mentioned anywhere except the encrypted one which you can use safely.

Hope this turtorial is helpful to you, please let your comments...

3 comments:

  1. Thanks Sagar for this solution.

    I have one question though,suppose I deploy application on two seperate machines having different Jboss servers of same version, and these servers are pointing to same DB, do I need to run this command to encrypt password two time? or can I use same encrypted password?

    ReplyDelete
    Replies
    1. There is no need to encrypt the password second time as the class that we are using SecureIdentityLoginModule is a kind of algorithm to encrypt password and it will be same nomatter the jboss server changes

      Delete