EVP_DecryptFinal_ex:bad decrypt when using Node.js

You mixed up two different encodings. See

cipher.update(data[, input_encoding][, output_encoding])

and

cipher.final([output_encoding])

and now look at

var encrypted = cipher.update(data, 'binary') + cipher.final('binary');

but it should be

var encrypted = cipher.update(data, 'binary', 'binary') + cipher.final('binary');

The issue is that cipher.update(data, 'binary') outputs a buffer which automatically stringifies to a Hex-encoded string instead of a "binary"-string.


Anyway, there is so much wrong with this code that you should start over and simply use an existing library that is highly opinionated.

  • You must have a random IV which is prepended to the ciphertext in order to reach semantic security.

  • A password has low entropy and cannot be used as a key. A single MD5 invocation doesn't change that fact. Key derivation from a password is supposed to be slow, so use a known scheme such as PBKDF2, bcrypt, scrypt or Argon2 (increasing security) with a high iteration count/cost factor. Don't forget the salt.

  • Authenticate your ciphertext with a message authentication code such as HMAC-SHA256 in an encrypt-then-MAC scheme. Otherwise, an attacker may manipulate ciphertexts and you won't even be able to detect changes. First step to losing data with a padding oracle attack.