EVP_DecryptFinal_ex:使用Node.js时解密不正确 [英] EVP_DecryptFinal_ex:bad decrypt when using Node.js
问题描述
使用以下节点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);
};
要执行,我运行了此
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:
错误:错误:06065064:数字信封 例程:EVP_DecryptFinal_ex:错误解密 错误时(本机) 在Decipheriv.Cipher.final(crypto.js:202:26)
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
和
现在看看
var encrypted = cipher.update(data, 'binary') + cipher.final('binary');
但应该是
var encrypted = cipher.update(data, 'binary', 'binary') + cipher.final('binary');
问题是cipher.update(data, '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.
-
您必须必须有一个随机IV,该IV会放在密文之前,以达到语义安全性.
You must have a random IV which is prepended to the ciphertext in order to reach semantic security.
密码的熵低,不能用作密钥.一次MD5调用不会改变这一事实.假定从密码派生密钥的速度很慢,所以请使用已知的方案,例如PBKDF2,bcrypt,scrypt或Argon2(提高安全性),并具有较高的迭代计数/成本因子.不要忘记盐.
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.
使用加密-然后-MAC方案中的消息认证代码(例如HMAC-SHA256)对密文进行认证.否则,攻击者可能会操纵密文,您甚至将无法检测到更改.通过填充Oracle攻击来丢失数据的第一步.
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.
这篇关于EVP_DecryptFinal_ex:使用Node.js时解密不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!