Security

Encrypted Preferences in Java

By Greg Travis, October 01, 2002

If you're using the Preferences API in Java, this encryption strategy lets you hide your preferences data in plain sight.

The Preferences API is now included in the core Java release, as of Version 1.4. It provides a simple, fully cross-platform mechanism for storing small amounts of data, and uses a simple hierarchical "name/value" structure for organizing data. It is intended to be used for configuration and preference data.

Preference data is stored differently on each platform. In fact, is entirely up to each Java implementation how it will store the actual data that is, what backing store it will use. In general, the backing store is not intended to be secure. For example, it may be implemented on top of the Registry, or some other storage facility that does not provide a way to hide sensitive data.

This article considers the technique of automatically encrypting data before storing it in the preferences database. This permits applications to use the Preferences API even for sensitive data, such as passwords and personal information.

What You'll Learn

This article is not intended to provide a tutorial on encryption. It is assumed that you already understand how encryption in Java works, or that you are willing to learn about it elsewhere.

This article focuses on integrating encryption techniques with the Preferences API. We won't focus on the many encryption algorithm options  we'll use a simple DES key to perform encryption and decryption, with the understanding that you may well want to replace this approach with another Java-based encryption method.

The most important aspect of this technique is making the encryption transparent. We want the encryption to happen behind-the-scenes, with as little intervention as possible. As you'll see, we'll be creating an EncryptedPreferences object, which acts just like a regular Preferences object except that it transparently takes care of encryption for us.

If you haven't ever used the Preferences API, don't worry. You'll pick up what you need to know along the way.

A Simple Test Program

Before we get into the details of how it all works, let's take a look at a simple test program. This program (pkg.Test) stores a couple of values in the preferences database.

The first two lines acquire a Preferences object for this program, "Test.class." Or rather, for the package it's contained in, "pkg." Remember, each package gets its own private area within the preferences database. The userNodeForPackage() method gets the Preferences object for our private area. This is the root node of the area in which we will store data.

Listing One: A simple test program. It stores a value in the preferences database
in the root node for its package ("pkg"), and another value in a subnode of
the root node.

The next line stores a value or rather, a key/value pair. The key is "not," and the value is "encrypted." Later on, you can ask for the value corresponding to the key "not," and you'll get back the value "encrypted."

The next two lines create a subnode of our main node. Into this subnode, we put another key/value pair. The key is "also not," and the value is "encrypted."

Finally, we take a look at what we've done by exporting the entire database that is, the entire database for our program. While the backing store might store data in any format, the exported data always uses the same format, which you can see in Listing Two.

If the data is being stored in the Registry, you can see it by using regedit. In my system, the preferences data is stored in \HKEY_CURRENT_USER\Software\ JavaSoft\Prefs\pkg, as you can see in
Figure 1.

Trying It with Encryption

Figure 1: The results of running pkg.Test

Using encrypted preferences is easy. Here's the encrypted version, pkg.encrypted.EncryptedTest, which does the same thing as pkg.Test, except that it uses encryption:

You can find the full source to pkg.encrypted.EncryptedTest in Listing Three.

Listing Three: A simple test program, this time using encryption. It does more
or less the same thing as the program in Listing One, except that this variant
uses an Encrypted Preferences object, which transparently encrypts the data
before storing it, and decrypts it before retrieving it.

The most important thing to see here is that instead of using the Preferences.userNodeForPackage() method, we're using the EncryptedPreferences.userNodeForPackage() method. And this method returns an EncryptedPreferences, rather than a regular Preferences object.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!