EVP_DecryptFinal_ex:在使用Node.js时进行坏解密。

时间:2022-06-28 15:23:26

Using the following 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);
};

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)

错误:错误:06065064:数字信封例程:EVP_DecryptFinal_ex:错误解密(本机)在Decipheriv.Cipher。最后(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.

我对密码学很陌生,所以不知道我为什么会收到这个错误。我现在只需要把它修好。

1 个解决方案

#1


3  

You mixed up two different encodings. See

你把两个不同的编码混在一起了。看到

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

密码。更新(数据(input_encoding][,output_encoding])

and

cipher.final([output_encoding])

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.

问题是那个密码。update(data, 'binary')输出一个缓冲区,该缓冲区自动将字符串绑定到十六进制编码的字符串,而不是“二进制”字符串。


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.

    为了达到语义安全性,必须在密文前面加上一个随机的IV。

  • 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.

    密码熵低,不能用作密钥。一个MD5调用不能改变这一事实。密码的关键派生应该是缓慢的,所以使用一个已知的方案,如PBKDF2、bcrypt、scrypt或Argon2(增加安全性),具有高迭代计数/成本因子。不要忘记你的盐。

  • 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.

    使用消息身份验证代码(比如加密后的mac方案中的HMAC-SHA256)对密码文本进行身份验证。否则,攻击者可能会操纵密文,而您甚至无法检测到更改。第一步是使用填充oracle攻击来丢失数据。

#1


3  

You mixed up two different encodings. See

你把两个不同的编码混在一起了。看到

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

密码。更新(数据(input_encoding][,output_encoding])

and

cipher.final([output_encoding])

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.

问题是那个密码。update(data, 'binary')输出一个缓冲区,该缓冲区自动将字符串绑定到十六进制编码的字符串,而不是“二进制”字符串。


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.

    为了达到语义安全性,必须在密文前面加上一个随机的IV。

  • 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.

    密码熵低,不能用作密钥。一个MD5调用不能改变这一事实。密码的关键派生应该是缓慢的,所以使用一个已知的方案,如PBKDF2、bcrypt、scrypt或Argon2(增加安全性),具有高迭代计数/成本因子。不要忘记你的盐。

  • 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.

    使用消息身份验证代码(比如加密后的mac方案中的HMAC-SHA256)对密码文本进行身份验证。否则,攻击者可能会操纵密文,而您甚至无法检测到更改。第一步是使用填充oracle攻击来丢失数据。