0

I'm trying to convert an mcrypt_encrypt function written in php to node.js, I am using CryptoJS in node.js and tried all kinds of config options and I am not having any luck figuring this thing out.

PHP CODE:

base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,md5($secretKey),$ldapPwd,MCRYPT_MODE_CFB,$initialVector))

JavaScript Code That I tried do not know what I am doing wrong:

var encrypted = CryptoJS.AES.encrypt(password, keyBase64,
{
    keySize: 128 / 8,
    iv: iv,
    mode: CryptoJS.mode.CFB,
    padding: CryptoJS.pad.NoPadding
});
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Prashanth Kumar B
  • 566
  • 10
  • 25

2 Answers2

1

The Cipher Feedback (CFB) mode is a family of block cipher modes with a segment size parameter. Mcrypt only supports CFB8 whereas CryptoJS only supports CFB128. They are incompatible.

I've implemented CFBb in CryptoJS which also supports 8-bit segments, but it is only tested for CryptoJS 3.1.2 and not the CryptoJS 2 version which is available through NPM.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Not entirely true ... mcrypt does have an 'ncfb' mode, there's just no constant defined for it in PHP. You can't just pass that string as the mode and it will work. – Narf Jul 31 '15 at 12:15
  • @Narf Didn't know that. That would answer the question, if the OP can change the PHP code which is unclear. Strangely enough, I downloaded the mcrypt source code to see if it supports variable CFB and haven't found it. I guess I just didn't look hard enough. – Artjom B. Jul 31 '15 at 12:22
  • Thank you, had to import another library, but however, cheers mate, all is well now :) – Prashanth Kumar B Aug 05 '15 at 08:41
1

In PHP, when you use mcrypt_module_open with Rijndael-128, you have to pass a 32 byte key and a 16 byte IV.

So with nodeJs, you can use the crypto module, for example :

var crypto = require('crypto');

//Declare our secret key
var key = 'fcda0ssdegfffc9441581bdd86484513dd9cb1547df2jsd';

//Declare our alogrithm
var algorithm = 'AES-256-CFB';

//Generate IV to hex format, so 8 * 2 = 16 bytes
var iv = crypto.randomBytes(8).toString('hex');

//Declare our string to encrypt
var password = 'HELLO WORLD';


var handler = {};

handler.encrypt64 = function(algorithm, key, vector, password){

    //create a cipher with an IV
    var cipher = crypto.createCipheriv(algorithm, key.substr(0,32), iv);

    //Encrypt our password from utf8 to hex
    var encrypted = cipher.update(password, 'utf8', 'base64'); 

    //Return any remaining enciphered data to hex format
    encrypted += cipher.final('base64');

    //Return a base64 String
    return encrypted;
};

handler.decrypt64 = function(algorithm, key, vector, password){

    //create a decipher with an IV
    var decipher = crypto.createDecipheriv(algorithm, key.substr(0, 32), iv);

    //Decrypt our encode data from base64 to utf8
    var decrypted = decipher.update(encode, 'base64', 'utf8');

    decrypted += decipher.final('utf8');


    //Return a utf8 string
    return decrypted;
};

var encode = handler.encrypt64(algorithm, key, iv, password);

var decode = handler.decrypt64(algorithm, key, iv, encode);
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Paul Boutes
  • 3,285
  • 2
  • 19
  • 22