AES 256 encryption using Java and Lotus Expeditor 6.2

In a recent engagement, one of the requirements for the application was the ability to encrypt the payload of an MQTT message using 256 bit Advanced Encryption Standard (AES) encryption, where the key was created using a combination of a user name and a pre-shared key. This was to be accomplished using the Lotus Expeditor Device JRE profile running on a desktop PC.

I’ve captured how I did this for posterity here, it’s basically the standard Java Cryptography Architecture (JCA) so should be generally useful in other domains too. I’ve used a really simple OSGi bundle that performs the cryptography in the start() method to prove the point within the Expeditor toolkit.

Creating a the encryption key

In this scenario, I needed to construct a 256 bit key derived from a user name and pre-shared key. Java provides the SecretKeySpec class to enable the provision of application specific data within a key.

// My user name
byte[] loginId = "galem".getBytes();
// A sample pre-shared key -- this might be something like an account number
// or employee number or such like.
byte[] preSharedKey = "ACME-1234ACME-1234ACME-1234".getBytes(); 
byte[] encodedKey = new byte[loginId.length + preSharedKey.length];
			
System.arraycopy(loginId, 0, encodedKey, 0, loginId.length);
System.arraycopy(preSharedKey, 0, encodedKey, loginId.length, preSharedKey.length);
			
// The SecretKeySpec provides a mechanism for application-specific generation
// of cryptography keys for consumption by the Java Crypto classes.
			
// Create a key specification first, based on our key input.
SecretKey aesKey = new SecretKeySpec(encodedKey, "AES");

Encrypting the data

Now we have the key, we can now create a Crypto class to encrypt the data. I’ve output the result to the console to show a “before and after” view.

// Create a Cipher for encrypting the data using the key we created.
Cipher encryptCipher = Cipher.getInstance("AES");
// Initialize the Cipher with key and parameters
encryptCipher.init(Cipher.ENCRYPT_MODE, aesKey);

// Our cleartext
String clearString = "This is another example";
byte[] cleartext = clearString.getBytes();

System.out.println("Plain text: "+clearString);

// Encrypt the cleartext
byte[] ciphertext = encryptCipher.doFinal(cleartext);

System.out.println("Encrypted: "+new String(ciphertext));

Decrypting the data back again

Finally, to show the encrypted data can be returned to its original form, we’ll reverse the process.

// Now decrypt back again...
// Decryption cipher
Cipher decryptCipher = Cipher.getInstance("AES");
// Initialize PBE Cipher with key and parameters
decryptCipher.init(Cipher.DECRYPT_MODE, aesKey);

// Decrypt the cleartext
byte[] deciphertext = decryptCipher.doFinal(ciphertext);

System.out.println("Decrypted: "+new String(deciphertext));

Full listing

package com.ibm.issw.sample.crypto;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;

/**
 * The activator class controls the plug-in life cycle
 */
public class Activator extends Plugin {

	// The plug-in ID
	public static final String PLUGIN_ID = "com.ibm.issw.sample.crypto";

	// The shared instance
	private static Activator plugin;
	
	/**
	 * The constructor.
	 */
	public Activator() {
	}

	/**
	 * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
	 */
	public void start(BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
		
		try {
			
		    // In this example we will just use a combination of a user name and 
		    // a pre-shared key.
			
		    // My user name
		    byte[] loginId = "galem".getBytes();
		    // A sample pre-shared key -- this might be something like an account number
		    // or employee number or such like.
		    byte[] preSharedKey = "ACME-1234ACME-1234ACME-1234".getBytes();

		    byte[] encodedKey = new byte[loginId.length + preSharedKey.length];
			
		    System.arraycopy(loginId, 0, encodedKey, 0, loginId.length);
		    System.arraycopy(preSharedKey, 0, encodedKey, loginId.length, preSharedKey.length);
			
		    // The SecretKeySpec provides a mechanism for application-specific generation
		    // of cryptography keys for consumption by the Java Crypto classes.
			
		    // Create a key specification first, based on our key input.
		    SecretKey aesKey = new SecretKeySpec(encodedKey, "AES");
			
		    // Create a Cipher for encrypting the data using the key we created.
		    Cipher encryptCipher = Cipher.getInstance("AES");
		    // Initialize the Cipher with key and parameters
		    encryptCipher.init(Cipher.ENCRYPT_MODE, aesKey);

		    // Our cleartext
		    String clearString = "This is another example";
		    byte[] cleartext = clearString.getBytes();

		    System.out.println("Plain text: "+clearString);
		    
		    // Encrypt the cleartext
		    byte[] ciphertext = encryptCipher.doFinal(cleartext);
		    
		    System.out.println("Encrypted: "+new String(ciphertext));
		    
		    // Now decrypt back again...	    		    
		    // Decryption cipher
		    Cipher decryptCipher = Cipher.getInstance("AES");
		    // Initialize PBE Cipher with key and parameters
		    decryptCipher.init(Cipher.DECRYPT_MODE, aesKey);
		    
		    // Decrypt the cleartext
		    byte[] deciphertext = decryptCipher.doFinal(ciphertext);
		    
		    System.out.println("Decrypted: "+new String(deciphertext));
		    
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		plugin = null;
		super.stop(context);
	}

	/**
	 * @return the shared instance
	 */
	public static Activator getDefault() {
		return plugin;
	}

}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s