4

I have text encoded with Blowfish using PHP's mcrypt:

$td = mcrypt_module_open ('blowfish', '', 'cfb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
mcrypt_generic_init ($td, "somekey", $iv);
$crypttext = mcrypt_generic ($td, "sometext");
mcrypt_generic_deinit ($td);
$res = base64_encode($iv.$crypttext);

When trying to decode the data with Node's crypto library I get garbage output.

var crypto = require("crypto"),
    ivAndCiphertext = "base64-encoded-ciphertext", 
    iv, cipherText, ivSize = 8, res= "";

ivAndCiphertext = new Buffer(ivAndCiphertext, 'base64');
iv = new Buffer(ivSize);
cipherText = new Buffer(ivAndCiphertext.length - ivSize);
ivAndCiphertext.copy(iv, 0, 0, ivSize);
ivAndCiphertext.copy(cipherText, 0, ivSize);

c = crypto.createDecipheriv('bf-cfb', "somekey", iv.toString("binary"));
res = c.update(cipherText, "binary", 'utf8');
res += c.final('utf8');

Any idea as to what I'm doing wrong?

EDIT

Using openssl (which the crypto library is a wrapper for) directly gives the same garbled result:

openssl enc -K the_key_in_hex bf-cfb -d -p -iv the_iv_in_hex -nosalt -nopad -a

So it doesn't look like a problem with the Javascript code.

aviaron
  • 640
  • 6
  • 11

3 Answers3

3

https://github.com/tugrul/node-mcrypt

Encrypt:

var mcrypt = require('mcrypt');

var bfEcb = new mcrypt.MCrypt('blowfish', 'cfb');
var iv = bfEcb.generateIv();

bfEcb.open('somekey', iv);

var cipherText = bfEcb.encrypt('sometext');

console.log(Buffer.concat([iv, cipherText]).toString('base64'));

Decrypt:

var mcrypt = require('mcrypt');
var bfEcb = new mcrypt.MCrypt('blowfish', 'cfb');

var ivAndCiphertext = new Buffer('AyvfjTyg24Y9fVCdjzRPEw==', 'base64');

var ivSize = bfEcb.getIvSize();
var iv = new Buffer(ivSize);
var cipherText = new Buffer(ivAndCiphertext.length - ivSize);

ivAndCiphertext.copy(iv, 0, 0, ivSize);
ivAndCiphertext.copy(cipherText, 0, ivSize);

bfEcb.open('somekey', iv);

console.log(bfEcb.decrypt(cipherText).toString());
tugrul
  • 136
  • 6
0

You are using ivAndCiphertext = "base64-encoded-ciphertext" followed directly by ivAndCiphertext = new Buffer(ivAndCiphertext, 'base64');. Your variable will point to the new buffer, so you get the result of decrypting the new buffer.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
0

I'm not sure if there are any other errors, but when using an IV you should use the createDecipheriv method:

http://nodejs.org/docs/latest/api/crypto.html#crypto.createDecipheriv

Linus Thiel
  • 38,647
  • 9
  • 109
  • 104
  • You're right, it was an error while copying the code. Fixed the question. – aviaron Jan 17 '12 at 14:30
  • Since the ciphertext is base64-encoded, I think you should do: `res = c.update(cipherText, "base64", 'utf8');` – Linus Thiel Jan 17 '12 at 14:44
  • `cipherText` is a `Buffer` and is interpreted as a binary encoded string when passed into `update`. – aviaron Jan 17 '12 at 19:48
  • Sorry, I missed that you read it into a buffer as base64. Well, considering it's the same with just openssl I don't think I can help! – Linus Thiel Jan 19 '12 at 13:24