Archive for August, 2015

AES Symmetric Encryption Using Javascript and ColdFusion

August 20, 2015

This article is just a small demo on how to use the same AES symmetric encryption on the client-side (javascript) and the server-side (ColdFusion).

TheĀ goal is to generate a key on the server-side (for example each time a user logs in, when the session is created, a unique key is generated and stored in the session), this key is then sent to the browser to encrypt form fields on the client-side which can then be sent encrypted to the server, where they can be decrypted again with the key from the session, to obtain the original values.

For completeness, I will show both how to encrypt and decrypt on the serverside first, using ColdFusion, as well as how to encrypt and decrypt on the client-side, using javascript.

For the generation of the key, I decided to use the underlying jvm, because the native ColdFusion generateKey method doesn’t allow for the generation of an InitializationVector, which leads to weaker security.

The ColdFusion example:

rawString = "Wazzaaaaaap";

// gimme a java KeyGenerator, SecretKey and InitializationVector
r = CreateObject("java","java.security.SecureRandom").init();
Cipher = CreateObject("java","javax.crypto.Cipher");
Iv = CreateObject("java","javax.crypto.spec.IvParameterSpec");
SecretKey = CreateObject("java","javax.crypto.SecretKey");
c = Cipher.getInstance("AES/CBC/PKCS5PADDING");
KeyGenerator = CreateObject("java","javax.crypto.KeyGenerator");

// generate IV
byteClass=createObject("Java","java.lang.Byte").TYPE;
newSeed = r.generateSeed(16);
r.setSeed(newSeed);
byteIV = createObject("Java","java.lang.reflect.Array").newInstance(byteClass, javacast("int", 16));
r.nextBytes(byteIV);
IV = Iv.init(byteIV);
jIV = binaryEncode( IV.getIV(), "base64" );

// generate Key
newSeed = r.generateSeed(32);
r.setSeed(newSeed);
keyGen = KeyGenerator.getInstance("AES");
sRandom = r.getInstance("SHA1PRNG");
keyGen.init(256, sRandom);
s_KEY = keyGen.generateKey();
jKey = binaryEncode( IV.getIV(), "base64" );

strToEncrypt = javacast("String", rawString);
writeOutput('strToencrypt: ');
writeDump(strToEncrypt);
byteToEncrypt = strToEncrypt.getBytes("UTF-8");
c.init(Cipher.ENCRYPT_MODE, s_KEY, IV, r);
encryptedBytes = c.doFinal(byteToEncrypt);

writeOutput('encryptedBytes: ');
writeDump(encryptedBytes);

c.init(Cipher.DECRYPT_MODE, s_KEY, IV);
plainByte = c.doFinal(encryptedBytes);
writeDump(plainByte);
plainText = toString(plainByte);
writeOutput('plainText: ');
writeDump(plainText);

For the javascript encryption/decryption, it’s easy to use an existing AES encryption library, like crypto-js on googlecode.

The JavaScript example:

CryptoJS: (Adjusted Original Example)

var text = "#rawString#";
var key = CryptoJS.enc.Base64.parse("#jKey#");
var iv = CryptoJS.enc.Base64.parse("#jIV#");

var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv});
console.log(encrypted.toString());

var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv});
console.log(decrypted.toString(CryptoJS.enc.Utf8));

That's all there is to it. You can encrypt client-side, decrypt server-side and vice-versa. In my example, i used a 256 bit key length, see keyGen.init(256,...).