Monday, February 27, 2012

Transparent Field Encryption/Decryption

Recently I have been working on expanding FRS integration with QuickBooks to include the Online Edition. While working on the transport pipe for QBOE (QuickBooks Online Edition), a realized requirement was the need to store a QBOE connection ticket. Something like this is usually a very simple task involving adding a new field to the appropriate domain object.

However in this case, one of the security rules that QBOE requires of an application is to store the connection ticket in an encrypted state. This is a common security requirement. Since the ticket acts as a key to QBOE, we don't want anybody with database access to get their hands on the actual ticket.

The first thought was to simply create a utility class to handle the encryption/decryption, possibly in a getter or setter. Another thought was to create a custom hibernate type that would handle the encryption/decryption by making use of an encryption utility class.

Upon doing some searching I came upon this: http://www.jasypt.org/  Basically Jasypt is just a java library that makes encryption extremely easy at the data layer. In fact all you need to do is get the appropriate jars on the classpath and do just a little configuration in the hibernate configuration, and voilĂ  encryption/decryption just works.

Here is an example of setting up the custom type in the hibernate configuration:

<typedef name="quickbooksEncryptedString" class="org.jasypt.hibernate3.type.EncryptedStringType">
      <param name="algorithm">PBEWithMD5AndDESparam>
      <param name="password">encyption-passwordparam>
      <param name="keyObtentionIterations">1000param>
typedef>

And the corresponding property mapping:

<property column="qb_online_connection_ticket" name="quickbooksOnlineConnectionTicket" type="quickbooksEncryptedString" length="1000"/>

Besides getting the Jasypt jars on the classpath, that is really all there is to it. With the above configuration the "quickbooksOnlineConnectionTicket" property is automatically encrypted when it is saved to the database and then automatically decrypted when it is retrieved. So from a coding perspective nothing changes. You can simply "set" the ticket and "get" the ticket whenever you need to.