Using the following node js:
var crypto = require('crypto');
var encrypt = function (input, password, callback) {
var m = crypto.createHash('md5');
m.update(password);
var key = m.digest('hex');
m = crypto.createHash('md5');
m.update(password + key);
var iv = m.digest('hex');
console.log(iv);
var data = new Buffer(input, 'utf8').toString('binary');
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv.slice(0,16));
var encrypted = cipher.update(data, 'binary') + cipher.final('binary');
var encoded = new Buffer(encrypted, 'binary').toString('base64');
callback(encoded);
};
var decrypt = function (input, password, callback) {
// Convert urlsafe base64 to normal base64
input = input.replace(/\-/g, '+').replace(/_/g, '/');
// Convert from base64 to binary string
var edata = new Buffer(input, 'base64').toString('binary');
// Create key from password
var m = crypto.createHash('md5');
m.update(password);
var key = m.digest('hex');
// Create iv from password and key
m = crypto.createHash('md5');
m.update(password + key);
var iv = m.digest('hex');
// Decipher encrypted data
var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv.slice(0,16));
var decrypted = decipher.update(edata, 'binary') + decipher.final('binary');
var plaintext = new Buffer(decrypted, 'binary').toString('utf8');
callback(plaintext);
};
To execute I ran this:
encrypt("uWeShxRrCKyK4pcs", "secret", function (encoded) {
console.log(encoded);
decrypt(encoded, "secret", function (output) {
console.log(output);
});
});
Encrypting seems to work fine, but when I try to decrypt, I receive the following error:
Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt at Error (native) at Decipheriv.Cipher.final (crypto.js:202:26)
I am pretty new to cryptography, so don't really know why I am receiving this error. I just need to get it fixed for now.
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');
Here the square brackets denote an optional function input. If you pass more values than are required then the additional values will be matched to the optional inputs from the left.
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.
As this question is the first one to appear on Google, here is another solution.
lifesaver bad decrypt
In case the link goes down, on my case, I had to update the decrypt function to add
function decrypt(text) {
let iv = Buffer.from((text.split(':')[1]).split('=')[0], 'hex')//will return iv;
let enKey = Buffer.from(text.split('=')[1], 'hex')//will return key;
let encryptedText = Buffer.from(text.split(':')[0], 'hex');//returns encrypted Data
let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(enKey), iv);
// Added this line here
decipher.setAutoPadding(false);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
//returns decryptedData
}
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