Encrypting sensitive information in persistent media
by ricardoz on Apr.06, 2008, under Articles, Security
If you ever deployed an application in a corporate environment, where an IT Security officer likes to keep a tight leash on who knows each system password, you probably needed to figure out some sort of security mechanism to store the passwords your application needs to connect to some database, access a web service, etc.
The most obvious and straightforward approach is to use a symmetric algorithm, like 3DES or AES, with an encryption password hard coded in your application to decrypt/encrypt the sensitive credentials. This has several cons:
- Anyone with access to the source code of the application can decrypt all sensitive data, ie you can’t guarantee the security officer that someone from your team/company won’t abuse this
- Anyone with access to the binary files of the application and a good de-compiler can decrypt all sensitive data, ie the security officer can’t even trust his IT production staff
- To change the encryption password you have to re-deploy the application
And these are just the 3 most important issues that come to mind in 5 minutes…
Anyway, issue 3 could be easily solved by placing the encryption password in an external file. But in my experience security guys doesn’t like to have their passwords in un-encrypted plan text files lying around in the file system.
I will present you here a simple approach that brings several improvements, and while not perfect (is security ever?) is very well received by at least all the security freaks I’ve encountered.
Concept

The method is based on using two encryption keys:
- A master key: typically hard-coded in our application, used only to encrypt/decrypt the application key
- An application key: used to actually encrypt/decrypt data, stored in a text file encrypted with master key
How then do we encrypt something:
- Load application key into memory (encrypted)
- Decrypt application key using master key
- Encrypt data using application key
And decrypt it in a similar fashion:
- Load application key into memory (encrypted)
- Decrypt application key using master key
- Decrypt data using application key
Regarding the application key, I recommend to use a randomly generated one, that is produced during application installation.
Implementation
The implementation of this method is quite simple. I will use Jasypt (www.jasypt.org) for symmetric encryption/decryption; Jasypt is a very cool API that wraps around JSEE and provides *very* simple methods to perform quite powerful encryption operations (encryption, hashing, etc.).
So, taking the concept described below our encryption routine should look something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public static String encryptUsingZoneKey(String masterKey, String zoneKeyFile, String data) throws IOException{ String result = null; String encryptedZoneKey = getZoneKey(zoneKeyFile); //Decrypt the zone key BasicTextEncryptor mkEncryptor = new BasicTextEncryptor(); mkEncryptor.setPassword(masterKey); String zoneKey = mkEncryptor.decrypt(encryptedZoneKey); // Encrypt the data BasicTextEncryptor zkEncryptor = new BasicTextEncryptor(); zkEncryptor.setPassword(zoneKey); result = zkEncryptor.encrypt(data); return result; } |
And the decryption routine:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public static String decryptUsingZoneKey(String masterKey, String zoneKeyFile, String encryptedData) throws IOException{ String result = null; String encryptedZoneKey = getZoneKey(zoneKeyFile); // Decrypt the zone key BasicTextEncryptor mkEncryptor = new BasicTextEncryptor(); mkEncryptor.setPassword(masterKey); String zoneKey = mkEncryptor.decrypt(encryptedZoneKey); // Decrypt the data BasicTextEncryptor zkEncryptor = new BasicTextEncryptor(); zkEncryptor.setPassword(zoneKey); result = zkEncryptor.decrypt(encryptedData); return result; } |
As you can see both are quite simple, they read the application key from a file to memory, decrypt it using the master key (hard coded in a class property in our code) and then perform the desired operation on the actual data.
Pros
- For a given person to gain decryption capabilities he/she needs to get access to *all* the source/binary code of the application, the application key file and the actual data. Most likely:
- the software people will have access only to the application source and binary code
- the production operators will have access only to the application binary code and data
- if needed, security officers can be locked out of the application binary code and/or data
- It doesn’t require any expensive hardware or software add-on
- Even though it’s a slight extra complication, it doesn’t involve much extra work to set-up and administer the application
Cons
- If two parties tag along they can gain decryption capabilities
- It implies a performance decrease since every encryption/decryption requires two steps