解密AES256节点。js返回错误的最终块长度

时间:2021-07-10 17:58:25

Using this Gist I was able to successfully decrypt AES256 in Node.js 0.8.7. Then when I upgraded to Node.js 0.10.24, I now see this error:

使用这个要点,我能够成功地在Node中解密AES256。js 0.8.7。然后升级到Node。我现在看到这个错误:

TypeError: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
at Decipheriv.Cipher.final (crypto.js:292:27)

类型错误:错误:0606506D:数字信封例程:EVP_DecryptFinal_ex: Decipheriv.Cipher错误的最终块长度。最后(crypto.js 292:27):

Here is the decrypt code from the Gist (shown here for convenience):

下面是来自要点的解密代码(为了方便起见,这里显示):

var crypto = require('crypto');

var AESCrypt = {};

AESCrypt.decrypt = function(cryptkey, iv, encryptdata) {
encryptdata = new Buffer(encryptdata, 'base64').toString('binary');

var decipher = crypto.createDecipheriv('aes-256-cbc', cryptkey, iv),
decoded = decipher.update(encryptdata);

decoded += decipher.final();
return decoded;
}

AESCrypt.encrypt = function(cryptkey, iv, cleardata) {
var encipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv),
encryptdata = encipher.update(cleardata);

encryptdata += encipher.final();
encode_encryptdata = new Buffer(encryptdata, 'binary').toString('base64');
return encode_encryptdata;
}

var cryptkey = crypto.createHash('sha256').update('Nixnogen').digest(),
iv = 'a2xhcgAAAAAAAAAA',
buf = "Here is some data for the encrypt", // 32 chars
enc = AESCrypt.encrypt(cryptkey, iv, buf);
var dec = AESCrypt.decrypt(cryptkey, iv, enc);

console.warn("encrypt length: ", enc.length);
console.warn("encrypt in Base64:", enc);
console.warn("decrypt all: " + dec);

3 个解决方案

#1


22  

Ok, so there was a change to Crypto in the switch from 0.8 to 0.10 Crypto methods return Buffer objects by default, rather than binary-encoded strings

好了,在从0。8到0。10的转换中有一个加密方法,默认情况下返回缓冲区对象,而不是二进制编码的字符串

This means the above code needs to specify encodings.

这意味着上面的代码需要指定编码。

These four lines:

这四行:

decoded = decipher.update(encryptdata);
decoded += decipher.final();
encryptdata = encipher.update(cleardata);
encryptdata += encipher.final();

Are changed to:

更改为:

decoded = decipher.update(encryptdata, 'binary', 'utf8');
decoded += decipher.final('utf8');
encryptdata = encipher.update(cleardata, 'utf8', 'binary');
encryptdata += encipher.final('binary');

This worked for me, but I am open to other suggestions.

这对我很有效,但我愿意接受其他的建议。

#2


9  

As your answer states, those functions work with Buffers now unless you specify an encoding. That said, you'd be better off avoiding binary encoded strings entirely and treat everything as Buffers until you strictly need a string for something. This way you can also use your encryption helpers to process non-text content.

正如您的答案所示,这些函数现在可以使用缓冲区,除非您指定一个编码。也就是说,您最好完全避免使用二进制编码的字符串,并将所有东西都当作缓冲区,直到您严格地需要一个字符串。这样,您还可以使用加密助手来处理非文本内容。

var crypto = require('crypto');

var AESCrypt = {};

AESCrypt.decrypt = function(cryptkey, iv, encryptdata) {
    var decipher = crypto.createDecipheriv('aes-256-cbc', cryptkey, iv);
    return Buffer.concat([
        decipher.update(encryptdata),
        decipher.final()
    ]);
}

AESCrypt.encrypt = function(cryptkey, iv, cleardata) {
    var encipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv);
    return Buffer.concat([
        encipher.update(cleardata),
        encipher.final()
    ]);
}

var cryptkey = crypto.createHash('sha256').update('Nixnogen').digest(),
iv = new Buffer('a2xhcgAAAAAAAAAA'),
buf = new Buffer("Here is some data for the encrypt"), // 32 chars
enc = AESCrypt.encrypt(cryptkey, iv, buf);
var dec = AESCrypt.decrypt(cryptkey, iv, enc);

console.warn("encrypt length: ", enc.length);
console.warn("encrypt in Base64:", enc.toString('base64'));
console.warn("decrypt all: " + dec.toString('utf8'));

#3


0  

My issue was that the string I was passing to my decrypt function was empty. I built in a check for empty strings and I did not receive the message again.

我的问题是,我传递给我的解密函数的字符串是空的。我构建了一个空字符串检查,但我没有再次收到消息。

decrypt: function(text){
                if(text.length == 0){
                    return text;
                }
                return this.decipher.update(text, 'hex', 'utf8') + this.decipher.final('utf8');
            }

#1


22  

Ok, so there was a change to Crypto in the switch from 0.8 to 0.10 Crypto methods return Buffer objects by default, rather than binary-encoded strings

好了,在从0。8到0。10的转换中有一个加密方法,默认情况下返回缓冲区对象,而不是二进制编码的字符串

This means the above code needs to specify encodings.

这意味着上面的代码需要指定编码。

These four lines:

这四行:

decoded = decipher.update(encryptdata);
decoded += decipher.final();
encryptdata = encipher.update(cleardata);
encryptdata += encipher.final();

Are changed to:

更改为:

decoded = decipher.update(encryptdata, 'binary', 'utf8');
decoded += decipher.final('utf8');
encryptdata = encipher.update(cleardata, 'utf8', 'binary');
encryptdata += encipher.final('binary');

This worked for me, but I am open to other suggestions.

这对我很有效,但我愿意接受其他的建议。

#2


9  

As your answer states, those functions work with Buffers now unless you specify an encoding. That said, you'd be better off avoiding binary encoded strings entirely and treat everything as Buffers until you strictly need a string for something. This way you can also use your encryption helpers to process non-text content.

正如您的答案所示,这些函数现在可以使用缓冲区,除非您指定一个编码。也就是说,您最好完全避免使用二进制编码的字符串,并将所有东西都当作缓冲区,直到您严格地需要一个字符串。这样,您还可以使用加密助手来处理非文本内容。

var crypto = require('crypto');

var AESCrypt = {};

AESCrypt.decrypt = function(cryptkey, iv, encryptdata) {
    var decipher = crypto.createDecipheriv('aes-256-cbc', cryptkey, iv);
    return Buffer.concat([
        decipher.update(encryptdata),
        decipher.final()
    ]);
}

AESCrypt.encrypt = function(cryptkey, iv, cleardata) {
    var encipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv);
    return Buffer.concat([
        encipher.update(cleardata),
        encipher.final()
    ]);
}

var cryptkey = crypto.createHash('sha256').update('Nixnogen').digest(),
iv = new Buffer('a2xhcgAAAAAAAAAA'),
buf = new Buffer("Here is some data for the encrypt"), // 32 chars
enc = AESCrypt.encrypt(cryptkey, iv, buf);
var dec = AESCrypt.decrypt(cryptkey, iv, enc);

console.warn("encrypt length: ", enc.length);
console.warn("encrypt in Base64:", enc.toString('base64'));
console.warn("decrypt all: " + dec.toString('utf8'));

#3


0  

My issue was that the string I was passing to my decrypt function was empty. I built in a check for empty strings and I did not receive the message again.

我的问题是,我传递给我的解密函数的字符串是空的。我构建了一个空字符串检查,但我没有再次收到消息。

decrypt: function(text){
                if(text.length == 0){
                    return text;
                }
                return this.decipher.update(text, 'hex', 'utf8') + this.decipher.final('utf8');
            }