Most Read This Week
By: Josh Eckels
Jul. 1, 2001 12:00 AM
The absence of standard and familiar Java APIs presents one of the biggest obstacles when developing for Java 2 Micro Edition (J2ME). Since J2ME targets much smaller devices, it lacks many libraries and features that are normally available in larger Java installations.
On Java 2 Standard Edition (J2SE) and Java 2 Enterprise Edition (J2EE), the Java Cryptography Architecture and Java Cryptography Extension help streamline the process of adding security to a project. The J2ME platform, however, lacks crypto APIs.
Of course, many J2ME devices, such as Palm handhelds, aren't suited for common cryptographic functions. Their constrained RAM and processors can make operations, such as public key cryptography, infeasible. Still, there's a real need for security on small devices, and they can perform a useful subset of cryptographic operations.
This article explores the use of cryptography on J2ME devices and walks though an implementation of a simple password-based encrypted database program. The database holds user login information and can be used to manage accounts for different machines and Web sites. Although the example targets J2ME for Palm handhelds, its design maximizes portability.
Modes are applied to ciphers to define their behavior. In the simplest mode, Electronic Code Book (ECB), each input block always produces the same output block. Although this makes implementation simple, the one-to-one mapping of input to output leaves the ciphertext vulnerable to attacks. Patterns in the encrypted data become apparent in the ciphertext if there are repeated input blocks, making cryptanalysis much easier.
The cipher block chaining (CBC) mode strengthens the ciphertext by making each block of ciphertext dependent on both the corresponding block of plaintext and all previous plaintext blocks as well. It uses an XOR feedback register to modify the plaintext before encrypting and after decrypting. At the start of an encryption or decryption operation, the XOR register is set to a randomly generated initialization vector (IV) that's transmitted or stored along with the ciphertext. It's not terribly important that the IV is truly random, but it should be different each time plaintext is encrypted with the same key.
Since plaintexts might be any length, extra bytes must be added to pad the input to a multiple of the block size in length. Public Key Cryptography Standard #5 (PKCS#5) padding is the most common padding scheme for symmetric block ciphers.
Choosing appropriate ciphers for J2ME requires special care, since most J2ME devices have relatively slow processors. Table 1 shows some rough benchmarks for a PalmV. The key setup column gives the time it takes for an algorithm to initialize itself with a key. The encryption column shows the amount of time it takes to encrypt one block (8 bytes) of data. Naturally, different implementations of the algorithms will have different performance. The data in Table 1 is by no means a definitive performance analysis.
For these implementations, TripleDES and Blowfish take significantly longer to initialize than DES, but Blowfish encrypts data faster than DES or TripleDES. Depending on the application, either key setup or encryption might dominate the running time. Choosing an appropriate cipher always involves weighing the trade-off between performance and the desired level of security.
Hashes, Passwords, and Keys
Applications commonly use hash functions to transform user-supplied passwords into symmetric keys. Several standards define techniques to convert passwords, but PKCS#5 specifies a simple technique: convert the password string to a byte array and use it as the input to a hash algorithm. The resulting digest serves as the key.
Running the password through a hash function serves several purposes. First, the hash function transforms variable length passwords into uniform-length hashes. Also, character strings follow certain patterns and good symmetric keys should be as close to random bytes as possible. Hashing the password removes the patterns, making cryptanalysis much harder.
Using a password-based key means that the key is only as secure as the password. If the number of likely passwords is smaller than the total number of keys, it's more efficient to search through all possible passwords than to attack the key directly. It's pointless to use a cipher with a huge key space unless users choose long passwords or passphrases. DES has a key space of 64 bits, of which only 56 are actually used. That's roughly equivalent to randomly selecting nine characters from the set upper- and lowercase letters and numbers. Users are unlikely to choose passwords longer than that for J2ME programs since text entry is typically inconvenient.
The dictionary attack is a common way to attack password-based systems. In it an attacker computes a list of keys from a dictionary of likely passwords. Once the attacker has obtained the encrypted data, he or she uses each potential key to decrypt the ciphertext until one of them produces meaningful plaintext.
A technique called salt helps guard against dictionary attacks. Salt is a set of random bytes that are stored unencrypted along with the ciphertext and are added to the password before it's hashed. It prevents an attacker from precomputing a list of keys since the password dictionary generates a different set of keys for each different salt value. Salt doesn't completely defeat a dictionary attack, but it does make it much more computationally intensive.
Implementing an Encrypted Password Database
The primary design goal for this application is to make it as simple as possible to port to different J2ME configurations and profiles. As presented, it targets the CLDC and a PalmOS-specific profile. It contains two device-specific groups of functionality: the GUI and the storage mechanism. The design accommodates different GUIs by separating the application's business logic and presentation. It solves the device-dependent storage problem using the Template pattern. An abstract superclass relies on methods in the concrete subclasses to store the data.
Another important goal is maintaining acceptable performance on the target device. Therefore, the design encapsulates the usage of the computationally intensive algorithms in a single class. Swapping in alternate hash functions or encryption algorithms makes it possible to customize the program for the performance characteristics of different devices. For this application, SHA1 and DES provide reasonable performance and are as secure as the expected passwords (see Figure 1)
The DES class throws a CipherException if it encounters a problem encrypting or decrypting. Possible problems include invalid parameters (like an IV that's not 8-bytes long or attempting to decrypt an array that's not a multiple of 8 bytes in length) and invalid padding after decryption. Normally, using the wrong key or IV will result in improperly padded plaintext.
The SiteInfo class wraps four strings: the site's name, location, username, and password. Each setter method trims the string to ensure it will be less than 127-bytes long (Java's maximum byte value). The class handles serializing its location, username, and password.
The SiteList class keeps track of all the SiteInfos in the system. It holds all the SiteInfos in a vector and is responsible for storing their name strings when it's serialized.
Since hashing the user's password, setting DES up for decryption, and decrypting the data are all computationally intensive operations, it's important to decrypt information only as needed. Keeping the site names in one byte array allows the application to start up faster because the application needs to display only the site names at startup. It can wait until the user selects a particular site to load and decrypts the rest of the SiteInfo data.
In this case, PalmEncryptedStorage subclasses EncryptedStorage and talks directly with the Palm's storage system, the database. The Palm-specific classes include com.sun.kjava.Database, a class that permits access to an application's database on the Palm, stored in a set of records. At startup the PalmEncryptedStorage checks if it has already created a database. If not, it makes a new one, generates salt, and stores it in record 0. The IV and ciphertext for the SiteList go in record 1. SiteInfos get stuffed into subsequent records. The SiteInfo at index 0 in the SiteList is kept in record 2, index 1 is kept in record 3, and so forth.
Listing 2 illustrates how the PalmEncryptedStorage interacts with the Palm's database. Three values identify each database: a creator ID (managed by Palm Computing at www.palmos.com/dev/tech/palmos/creatorid/), a database type ID, (separates different applications from a single creator ID), and a database type string (shown in the list of databases in the Palm's memory-usage list).
The class's constructor tries to open an existing database. If it can't find one, it creates a new one, opens it, and stores the 8-byte salt value. The setRecordBytes() method sets the bytes of the specified record index. If a record at that index already exists, it's overwritten; if no record exists, a new record is appended.
In this program an abstract class, AbstractSpotlet, draws the familiar Palm UI tab at the top of the screen to show the user which application is running. It also keeps a reference to the PalmPassword object so that the Spotlet can interact with the rest of the application. There are three subclasses, one for each screen in the UI.
The first is the LoginSpotlet. It gets the password from the user and informs him or her if the password was not correct. SiteListSpotlet shows the list of sites and permits the user to either select one to display or create a new entry (see Figure 3). The SiteInfoSpotlet allows the user to view and edit a site's information and then save it (see Figure 4).
Unfortunately, the Palm-specific classes don't include a list GUI widget. The ListBox class provided works like list boxes in other Palm applications. It's backed by a ListBoxModel that supplies the data to be displayed and sends selection events to a ListBoxListener. It calculates the number of elements that can fit vertically, based on the size of the box, and draws as many elements from the ListBoxModel as can fit. It uses the Palm-specific ScrollBar widget to handle scrolling, shifting the elements displayed in response to user input. If the user selects one of the elements in the list, the ListBox notifies its ListBoxListener that an element in the list was selected.
The PalmPassword class contains the main method for the application and acts as a controller for the system. It instantiates the three Spotlets that all keep a reference to the PalmPassword object. When the Spotlets get events from the user, they call methods in the controller to process the request and display other Spotlets as needed.
Building and Running the Application
Setting up an IDE or a build tool to handle the process will save a lot of time, as will installing an emulator for the target device on the development workstation. Sun provides detailed installation and usage instructions for the J2ME libraries and utilities.The page also describes how to get a Palm emulator and transfer a ROM image from a Palm device.
Unfortunately, the section labeled "The J2ME CLDC Development Environment" contains a couple of errors. So run the following commands from the c:\j2me_cldc\tools\palm\ directory instead:
The build.bat file included with the source compiles the source code, preverifies the compiled classes, stores the results in .\preverified, and builds them into a Palm application. Be sure to edit the first line of the batch file to point to the proper directory. After installing the KVM as documented by Sun, simply drag-and-drop PalmPassword.prc onto an emulator or HotSync it to a Palm device and run it.
Although the example program is functional, it's still far from feature-complete. As presented there's no way to delete a SiteInfo from the list or sort the list. The application could give the user some sort of progress bar during the password hashing and key setup. More fields might be added to let the user input more information about a site, or the ListBox could be changed to display more than just the site's name. Also, if something goes wrong with encryption or decryption, it would be nice to inform the user instead of just swallowing the exception.
A conduit that synchronizes data with an application on the user's desktop machine might also be useful. Because all the device-specific code is kept isolated, it would be simple to create a Swing-based application that could read the encrypted data and allow the user to manage the password database.
It's important to remember that cryptography doesn't automatically make a system secure. For this application, a poorly chosen password will reduce the security significantly. Also, it's necessary to exit the program after use or the passwords will be vulnerable to anyone who happens upon the device. Even the best security is still only risk management.
Just posted is a follow-up to my article in the current issue of JDJ, describing how to port my application to MIDP and including the full source code. The link is available at http://www.isnetworks.com/j2meCrypto/. This is a follow-up to "J2ME Cryptography," an article published in the July 2001 issue of Java Developer's Journal.
Reader Feedback: Page 1 of 1
Subscribe to the World's Most Powerful Newsletters
Today's Top Reads