Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created July 9, 2016 12:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennadel/4db4aaa2f49852cb7b5f0f8ccc181fc9 to your computer and use it in GitHub Desktop.
Save bennadel/4db4aaa2f49852cb7b5f0f8ccc181fc9 to your computer and use it in GitHub Desktop.
Using AES / ECB / PKCS5Padding Encryption In ColdFusion And Decrypting Values In Node.js
<cfscript>
// I am the value that we will be encrypted and decrypting.
input = "Get out back and hold the monkey!";
// Generated using generateSecretKey( "AES", 128 ).
encryptionKey = "JZidBZLaYf27huVuM4MNTA==";
// Put the input through the encryption and decryption life-cycle using the AES
// algorithm and the default [AES], [IVorSalt], and [iterations] values.
// --
// NOTE: ColdFusion uses "AES/ECB/PKCS5Padding" as the default configuration which
// we can demonstrate by using the default configuration to encrypt and then the
// more explicit configuration to decrypt.
encryptedInput = encrypt( input, encryptionKey, "AES", "base64" );
decryptedInput = decrypt( encryptedInput, encryptionKey, "AES/ECB/PKCS5Padding", "base64" );
// Output the all the values, including an input / output test.
writeOutput( "Input: #input# <br />" );
writeOutput( "Encrypted Input: #encryptedInput# <br />" );
writeOutput( "Decrypted Input: #decryptedInput# <br />" );
writeOutput( "Values Match: #( compare( input, decryptedInput ) eq 0 )#" );
</cfscript>
// Require the core node modules.
var crypto = require( "crypto" );
// I am the value that we will be encrypted and decrypting.
var input = "Get out back and hold the monkey!";
// In Node, we need to use the same AES secret key that we generated and used in
// our ColdFusion encryption algorithm.
// --
// Generated using generateSecretKey( "AES", 128 ).
var encryptionKey = "JZidBZLaYf27huVuM4MNTA==";
// I am the encrypted input value as generated by ColdFusion's encrypt() method.
// --
// NOTE: encrypt( input, encryptionKey, "AES", "base64" );
var coldfusionEncryptedValue = "TmiHZg7CvY+92iNxzp+nR6gX9ynpKmc5t6ZP1sZLU5UzCAN601RDfyOuGu3fq8jh";
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
// The CipherIV methods must take the inputs as a binary / buffer values.
var binaryEncryptionKey = new Buffer( encryptionKey, "base64" );
var binaryIV = new Buffer( 0 );
// It was the use of an empty IVorSalt value that really blocked us for a while in
// getting this to work. The biggest challenge when performing cryptography across
// different technologies is marking sure that the algorithms line-up exactly otherwise
// the values won't be correct. In ColdFusion, we didn't provide an initialization
// vector; as such, in Node, we have to do the same thing by EXPLICITLY providing an
// EMPTY IV value.
// --
// NOTE: If we had used the crypto.createCipher() method instead, the IV value would
// have been derived from the encryption key, which is definitely not what we wanted.
var cipher = crypto.createCipheriv( "AES-128-ECB", binaryEncryptionKey, binaryIV );
// When encrypting, we're converting the UTF-8 input to Base64 output.
var encryptedInput = (
cipher.update( input, "utf8", "base64" ) +
cipher.final( "base64" )
);
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
var decipher = crypto.createDecipheriv( "AES-128-ECB", binaryEncryptionKey, binaryIV );
// When decrypting we're converting the Base64 input to UTF-8 output.
var decryptedInput = (
decipher.update( encryptedInput, "base64", "utf8" ) +
decipher.final( "utf8" )
);
// Output the all the values, including an input / output test for ColdFusion and
// Node.js to see if the encrypted values match.
console.log( "Input:", input );
console.log( "Encrypted Input:", encryptedInput );
console.log( "Decrypted Input:", decryptedInput );
console.log( "Values Match:", ( input === decryptedInput ) );
console.log( "ColdFusion / Node Match:", ( coldfusionEncryptedValue === encryptedInput ) );
@owenallenaz
Copy link

7 years later and the zero-length IV proved invaluable. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment