I am totally confused why this isn't working, I am getting Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
var crypto = require('crypto');
var key = "ciw7p02f70000ysjon7gztjn7";
var pt = "72721827b4b4ee493ac09c635827c15ce014c3c3";
var encrypt = crypto.createCipher('aes256', key);
encrypt.update(pt, 'utf8', 'hex');
var encrypted = encrypt.final('hex')
var decrypt = crypto.createDecipher('aes256', key);
decrypt.update(encrypted, 'hex', 'utf8')
decrypt.final()
You can see it action using RunKit ... https://runkit.com/fredyc/bidirectional-encryption-with-nodejs
Solution via https://github.com/nodejs/node-v0.x-archive/issues/6386
// https://github.com/nodejs/node-v0.x-archive/issues/6386#issuecomment-31817919
// with createCipher / createDecipher (both deprecated) replaced with
// createCipheriv / createDecipheriv and a generated IV passed along.
var assert = require('assert');
var crypto = require('crypto');
var algorithm = 'aes256';
var inputEncoding = 'utf8';
var outputEncoding = 'hex';
var ivlength = 16 // AES blocksize
var key = Buffer.from('ciw7p02f70000ysjon7gztjn7c2x7GfJ', 'latin1'); // key must be 32 bytes for aes256
var iv = crypto.randomBytes(ivlength);
var text = '72721827b4b4ee493ac09c635827c15ce014c3c3';
console.log('Ciphering "%s" with key "%s" using %s', text, key, algorithm);
var cipher = crypto.createCipheriv(algorithm, key, iv);
var ciphered = cipher.update(text, inputEncoding, outputEncoding);
ciphered += cipher.final(outputEncoding);
var ciphertext = iv.toString(outputEncoding) + ':' + ciphered
console.log('Result in %s is "%s"', outputEncoding, ciphertext);
var components = ciphertext.split(':');
var iv_from_ciphertext = Buffer.from(components.shift(), outputEncoding);
var decipher = crypto.createDecipheriv(algorithm, key, iv_from_ciphertext);
var deciphered = decipher.update(components.join(':'), outputEncoding, inputEncoding);
deciphered += decipher.final(inputEncoding);
console.log(deciphered);
assert.equal(deciphered, text, 'Deciphered text does not match!');
the usage error is here:
// yours (incorrect)
var encrypt = crypto.createCipher('aes256', key);
encrypt.update(pt, 'utf8', 'hex');
var encrypted = encrypt.final('hex')
// correct
var encrypt = crypto.createCipher('aes256', key);
var encrypted = encrypt.update(pt, 'utf8', 'hex');
encrypted += encrypt.final('hex')
// yours (incorrect)
var decrypt = crypto.createDecipher('aes256', key);
decrypt.update(encrypted, 'hex', 'utf8')
decrypt.final()
// correct
var decrypt = crypto.createDecipher('aes256', key);
var decrypted = decrypt.update(encrypted, 'hex', 'utf8')
decrypted += decrypt.final()
but because cipher.createCipher()
and cipher.createDecipher()
are now deprecated and insecure, the solution above uses cipher.createCipheriv()
and cipher.createDecipheriv()
, instead.
The addition of a random IV protects you from leaking information if you encrypt multiple plaintexts that share the first same 16 bytes (or multiple of 16 bytes) at the start of the message. See Encrypting using AES 256, do I need IV?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With