Sandro Munda Sandro Munda - 1 month ago 23
Node.js Question

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.

Answer

The encrypted data starts with a 8 byte "magic" indicating that there is a salt. 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.