Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with nodejs crypto decipher?

I have the following encrypted data:

U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o

The pass to decrypt it is: password

(it's the example from gibberish-aes)

In the command line using openssl:

echo "U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o" | openssl enc -d -aes-256-cbc -a -k password

The output is:

Made with Gibberish\n

With my NodeJS application:

  var decipher = crypto.createDecipher('aes-256-cbc', "password");
  var dec = decipher.update("U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o",
     'base64', 'utf8');
  dec += decipher.final('utf8');

I have the following error TypeError: DecipherFinal fail at the decipher.final line.

Am I missing something ? Thanks.

like image 819
Sandro Munda Avatar asked Aug 31 '12 16:08

Sandro Munda


1 Answers

The encrypted data starts with a 8 byte "magic" indicating that there is a salt (the ASCII encoding of "Salted__"). Then the next 8 bytes is the salt. Now the bad news: Node.js does not seem to use the salt for the EVP_BytesToKey method:

int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL,
  (unsigned char*) key_buf, key_buf_len, 1, key, iv);

That NULL is the salt.

This has been verified using a Java test application (using the right salt) - the result string was returned.

Please leave out the salt using the OpenSSL -nosalt switch and try again.

[EXAMPLE]

OpenSSL CLI:

openssl enc -aes-256-cbc -nosalt -a -k password
owlstead
Mh5yxIyZH+fSMTkSgkLa5w==

NodeJS crypto:

var crypto=require('crypto')
var cipher=crypto.createDecipher('aes-256-cbc', "password")
var enc = cipher.update("Mh5yxIyZH+fSMTkSgkLa5w==", 'base64', 'utf8')
enc += cipher.final('utf8')

[LATE EDIT] Note that using secret key derivation with a salt and large work factor may be paramount to security. You'd better use a very unique, high entropy password otherwise your encrypted data may be at risk.


[REALLY LATE EDIT] OpenSSL 1.1.0c changed the digest algorithm used in some internal components. Formerly, MD5 was used, and 1.1.0 switched to SHA256. Be careful the change is not affecting you in both EVP_BytesToKey and commands like openssl enc.

like image 69
Maarten Bodewes Avatar answered Nov 20 '22 20:11

Maarten Bodewes