javascriptencryptionaescryptojsecb

CryptoJS javascript AES-128, ECB encrypt / decrypt


Goal: Simple CryptoJS example to encrypt, decrypt using AES-128, ECB, 0-padding.

See below my runnable sample.

Input text is "US0378331005-USD-US-en" which is encrypted (hopefully AES-128 with all the above) and then decrypted (which does not work)

text: US0378331005-USD-US-en
key: 11A1764225B11AA1
key length: 16
encrypted 951422f8ac8354acf23fbc
decrypted a5126fa0fc3cb4c39a4f3e637be98a73

var text = 'US0378331005-USD-US-en';
var key = '11A1764225B11AA1'; // to ensure AES-128 this has to be 16 bit

console.log('text:', text);
console.log('key:', key);
console.log('key length:', key.length );

text = CryptoJS.enc.Hex.parse(text);
key = CryptoJS.enc.Hex.parse(key);
var iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");

var encrypted = CryptoJS.AES.encrypt(text, key, { iv: iv, mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding });
encrypted = encrypted.ciphertext.toString(CryptoJS.enc.Hex);

console.log('encrypted', encrypted);

var decrypted =  CryptoJS.AES.decrypt(encrypted, key, {iv: iv, mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding });

console.log('decrypted', decrypted.toString() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/aes.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/md5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/enc-hex.min.js"></script>


Solution

  • There are several bugs in your code:

    Fixed code:

    var text = 'US0378331005-USD-US-en';
    var key = '11A1764225B11AA1'; 
    
    console.log('text:', text);
    console.log('key:', key);
    console.log('key length:', key.length );
    
    // Fix: Use the Utf8 encoder
    text = CryptoJS.enc.Utf8.parse(text); 
    // Fix: Use the Utf8 encoder (or apply in combination with the hex encoder a 32 hex digit key for AES-128)
    key = CryptoJS.enc.Utf8.parse(key); 
    
    // Fix: Apply padding (e.g. Zero padding). Note that PKCS#7 padding is more reliable and that ECB is insecure
    var encrypted = CryptoJS.AES.encrypt(text, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.ZeroPadding }); 
    encrypted = encrypted.ciphertext.toString(CryptoJS.enc.Hex);
    console.log('encrypted', encrypted);
    
    // Fix: Pass a CipherParams object (or the Base64 encoded ciphertext)
    var decrypted =  CryptoJS.AES.decrypt({ciphertext: CryptoJS.enc.Hex.parse(encrypted)}, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.ZeroPadding }); 
    
    // Fix: Utf8 decode the decrypted data
    console.log('decrypted', decrypted.toString(CryptoJS.enc.Utf8)); 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>