Search code examples
javascriptaesnode-redcryptojs

Decoding AES-CTR messages in Node-RED


I having trouble decrypting AES-CTR payloads in Node-RED.

As an example I am encoding "Message" here -> https://cryptii.com/pipes/aes-encryption - and then decrypting that result in Node-RED.

Crytii Site Results:
Input: 4d657373616765
Algorithm: AES-128
Mode: CTR
Key: 000102030405060708090a0b0c0d0e0f
IV: 101112131415161718191a1b1c1d1e1f
Output: 4a9b9c0780b266

When decrypting the output payload from Cryptii (4a9b9c0780b266) in Node-RED I am getting a "" returned in the debug widow.

var cryptojs = context.global.cryptojs;

var key = '000102030405060708090a0b0c0d0e0f';
var iv = '101112131415161718191a1b1c1d1e1f';
var data = msg.payload;

var message = cryptojs.AES.decrypt(
    data, 
    key, { 
        mode: cryptojs.mode.CTR, 
        iv: iv }
    );

msg.payload = message.toString();

return msg;

This is the libary used: https://www.npmjs.com/package/crypto-js and required changes made to settings.js for Node-RED.

My understanding of the subject matter is limited and any guidance would be appreciated. TIA


Solution

  • Key, IV and ciphertext are hex encoded and therefore must be parsed with the hex encoder and converted to WordArrays (also CryptoJS applies a key derivation function if the key is passed as a string).

    The ciphertext must be passed as a CipherParams object.

    CTR is a stream cipher mode and does not use padding. In CryptoJS padding must be explicitly disabled, otherwise the default padding (PKCS7) is applied.

    var key = CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f'); // hex decode
    var iv = CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f'); // hex decode
    var data = CryptoJS.enc.Hex.parse('4a9b9c0780b266'); // hex decode
    
    var message = CryptoJS.AES.decrypt(
        {ciphertext: data}, // pass ciphertext as CipherParams object 
        key, { 
            mode: CryptoJS.mode.CTR, 
            iv: iv,
            padding: CryptoJS.pad.NoPadding // disable padding
       }
    );
    
    console.log(message.toString()); // hex encode
    console.log(message.toString(CryptoJS.enc.Utf8)); // UTF-8 decode
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>