This is probably due to the size of the plaintext rather than the type of characters used. You need to concatenate the response from update()
with the response from final()
. Don't use +=
operator, it does not always work on arrays.
Node.js Crypto cipher special characeters
-
28-09-2022 - |
Question
I am trying to field level encrypt data in Node using the crypto library.
It seems to work just fine, except with special characters like $ and -
Ex "Price-Smith"
Not sure why
function encrypt(data, key) {
if (data === null)
return null
else if (typeof data === 'undefined')
return undefined;
else if (data === '')
return '';
var iv = crypto.randomBytes(16);
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
cipher.update(data, 'utf8', 'binary');
return Buffer.concat([iv, cipher.final()]).toString('base64');
}
function decrypt(cipher, key) {
if (cipher === null)
return null
else if (typeof cipher == 'undefined')
return undefined;
else if (cipher === '')
return '';
var cipher = new Buffer(cipher, 'base64');
var iv = cipher.slice(0, 16);
var ciphertext = cipher.slice(16);
var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
decipher.update(ciphertext, 'binary', 'utf8');
return decipher.final('utf8');
}
Error
TypeError: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
at Decipheriv.Cipher.final (crypto.js:287:27)
A separate IV is used for each field value, otherwise fields values that are the same would have the same cipher. So I store the IV as the first 16 bytes and splice it off before decryption. Maybe this could be my problem area?
Thanks! Andrew
La solution
Autres conseils
Thanks @owlstead! Here is the working code:
function encrypt(data, key) {
if (data === null)
return null
else if (typeof data === 'undefined')
return undefined;
else if (data === '')
return '';
var iv = crypto.randomBytes(16);
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
var encrypted = [cipher.update(data)];
encrypted.push(cipher.final());
return Buffer.concat([iv, Buffer.concat(encrypted)]).toString('base64');
}
function decrypt(cipher, key) {
if (cipher === null)
return null
else if (typeof cipher == 'undefined')
return undefined;
else if (cipher === '')
return '';
var cipher = new Buffer(cipher, 'base64');
var iv = cipher.slice(0, 16);
var ciphertext = cipher.slice(16);
var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
var decrypted = [decipher.update(ciphertext)];
decrypted.push(decipher.final());
return Buffer.concat(decrypted).toString('utf8');
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow