3

I am doing Encryption and Decryption using both NodeJS Crypto and CryptoJS library in both front-end and backend. I am able to do the encryption using NodeJS Crypto which works perfectly fine and the encrypted string is also consistent with the Java encryption. But when I use, CryptoJS library the encryption string does not as expected. I provide below the standalone Typescript code.

Please help me. I am using aes-256-cfb8 Algorithm. Is it because of this Algorithm which may not be supported by CryptoJS library? Please give me some direction, I am struck now.

import * as crypto from "crypto";
import CryptoJS, { mode } from "crypto-js";

export class Test3 {

    private static readonly CRYPTO_ALGORITHM = 'aes-256-cfb8'
    private static readonly DEFAULT_IV: string = "0123456789123456";

    // NodeJS Crypto - Works fine
    public encryptValue(valueToEncrypt: string, secretKey: string): string {
        let encryptedValue: string = '';
        const md5 = crypto.createHash('md5').update(secretKey).digest('hex');
        const key: string = md5;
        console.log("MD5 Value : ", md5);
        const iv = Buffer.from(Test3.DEFAULT_IV)
        console.log("iv: ", iv)
        const cipher = crypto.createCipheriv(Test3.CRYPTO_ALGORITHM, key, iv);
        let encrypted = cipher.update(valueToEncrypt, 'utf8', 'base64');
        console.log("encrypted ::: ", encrypted);
        encrypted += cipher.final('base64');
        encryptedValue = encrypted;
        return encryptedValue;
    }

    // CryptoJS library - does not work
    public check3(valueToEncrypt: string, secretKey: string): void {
        const hash = CryptoJS.MD5(secretKey);
        const md5Key: string = hash.toString(CryptoJS.enc.Hex)
        console.log("MD5 Value: ", md5Key); // Upto correct

        const IV11 = CryptoJS.enc.Utf8.parse(Test3.DEFAULT_IV);
        const key11 = CryptoJS.enc.Utf8.parse(md5Key);
        const data = CryptoJS.enc.Utf8.parse(valueToEncrypt);

        const enc1 = CryptoJS.AES.encrypt(data, key11, { 
            format: CryptoJS.format.OpenSSL,
            iv: IV11,
            mode: CryptoJS.mode.CFB,
            padding: CryptoJS.pad.NoPadding
            
          });
          console.log("Cipher text11: ", enc1.toString());
        
    }
}

const text2Encrypt = "A brown lazy dog";
const someSecretKey: string = "projectId" + "~" + "India";
const test = new Test3();

// Using NodeJS Crypto
const enc = test.encryptValue(text2Encrypt, someSecretKey);
console.log("Encrypted Value Using NodeJS Crypto: ", enc); // ===> nJG4Fk27JZ7E5klLqFAt

// Using CryptoJS 
console.log("****************** Using CryptoJS ******************")
test.check3(text2Encrypt, someSecretKey);

Please help me for the method check3() of the above class. Also I have checked many links in SO.

Topaco
  • 40,594
  • 4
  • 35
  • 62
Sambit
  • 7,625
  • 7
  • 34
  • 65

1 Answers1

2

You suspect right. Both codes use different variants of the CFB mode. For CFB a segment size must be defined. The segment size of the CFB mode corresponds to the bits encrypted per encryption step, see CFB.

The crypto module of NodeJS supports several segment sizes, e.g. 8 bits (aes-256-cfb8) or 128 bits (aes-256-cfb), while CryptoJS only supports a segment size of 128 bits (CryptoJS.mode.CFB).

If the segment size is changed to 128 bits (aes-256-cfb) in the crypto module, both ciphertexts match.

Edit:
In this post you will find an extension of CryptoJS for the CFB mode, so that also a variable segment size, e.g. 8 bits, is supported.

Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Thanks @Topaco, both encrypted string when I change to `aes-256-cfb` this algorithm. But in my case it should be `aes-256-cfb8`, because it has been implemented by me in Java also which can not be used as it has been used by many modules. – Sambit Jun 18 '21 at 11:08
  • Thanks a lot @Topaco. I made some changes as per Typescript structure to make it work. It is working fine. Accepted your inputs and direction. – Sambit Jun 18 '21 at 15:04