RESTful Hullabaloo | Home | An Intern's Experience; or How Code Learns

Filed under Quick Tips on August 26, 2008 by Doug Burns

Securing Java Objects for Plain Text Transport

Recently I needed a way to secure some data that was going to be placed into an XML document. By using the Java APIs SealedObject class, along with the public domain Base64 class, I was able to secure an entire object, then encode it as text for inclusion in the XML.

To accomplish this, I created a class called Encrypter which provides one method for encryption and serialization, and another for reversing the process. I've listed the code for that class below, as well as another that demonstrates its use.

Update: We have posted the source for Encrypter, along with a compiled .jar to the Arc90 lab.

Encrypter Class

package com.arc90.example;

import java.io.Serializable;
import javax.crypto.Cipher;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * Utility for encrypting/serializing and deserializing/decrypting objects
 *
 * @param <T> The type of object this Encrypter will accept and return
 */
public class Encrypter<T>
{	
	/**
	 * Encrypts and serializes the given object using the given password.
	 * 
	 * @param object The object to encrypt and serialize
	 * @param password The password to be used for encryption
	 * @return A Base64 representation of the encrypted object
	 */
	public String encryptAndSerialize(T source, String password) 
	{
		if(!(source instanceof Serializable))
		{
			throw new IllegalArgumentException("Source object must implement Serializable.");
		}
		try
		{
			SecretKey key = buildSecretKey(password);
			Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, key);
			SealedObject sealedObject = new SealedObject((Serializable) source, cipher);
			
			return Base64.encodeObject(sealedObject);
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * Deserializes and decrypts the Java object from the given cipher text.
	 * 
	 * @param cipherText Base64 representation of the encrypted object
	 * @param password The password that was used for encryption
	 * @return The unencrypted object
	 */
	@SuppressWarnings("unchecked")
	public T deserializeAndDecrypt(String cipherText, String password)
	{
		try
		{
			SecretKey key = buildSecretKey(password);
			Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
			cipher.init(Cipher.DECRYPT_MODE, key);
			
			SealedObject sealedObject = (SealedObject) Base64.decodeToObject(cipherText);
			
			return (T) sealedObject.getObject(cipher);
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * Builds a secret key from a text password
	 * 
	 * @param password The password to be used when generating the key
	 * @return The generated key
	 * @throws Exception
	 */
	private SecretKey buildSecretKey(String password) throws Exception
	{
		byte[] passwordBytes = password.getBytes();
		DESKeySpec keySpec = new DESKeySpec(passwordBytes);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		return keyFactory.generateSecret(keySpec);
	}
}

Demo Class

package com.arc90.example;

import java.util.ArrayList;
import java.util.List;

/**
 * Demonstrates use of the Encrypter class
 */
public class Demo
{
	private static final String PASSWORD = "YOUR_PASSWORD";
	
	@SuppressWarnings("unchecked")
	public static void main(String[] args)
	{
		List<Integer> secrets = new ArrayList<Integer>();
		secrets.add(4);
		secrets.add(8);
		secrets.add(15);
		secrets.add(16);
		secrets.add(23);
		secrets.add(42);
		
		Encrypter<List<Integer>> encrypter = new Encrypter<List<Integer>>();
		
		/*
		 * Encrypt and serialize the object
		 */
		String cipherText = encrypter.encryptAndSerialize(secrets, PASSWORD);
		System.out.println(cipherText);
		
		/*
		 * Deserialize and decrypt the string
		 */
		List<Integer> out = encrypter.deserializeAndDecrypt(cipherText, PASSWORD);
		for(Integer i : out)
		{
			System.out.println(i);
		}
	}
}

Post a Comment Digg Del.icio.us

Trackback Pings (TrackBack URL for this entry)

http://www.arc90.com/cgi-bin/mt4/mt-tb.cgi/184.

Post a Comment:

RESTful Hullabaloo | Main | An Intern's Experience; or How Code Learns