【问题标题】:Decrypting AES256 with node.js returns wrong final block length使用 node.js 解密 AES256 返回错误的最终块长度
【发布时间】:2014-02-13 01:18:52
【问题描述】:

使用这个Gist 我能够成功解密 Node.js 0.8.7 中的 AES256。然后当我升级到 Node.js 0.10.24 时,我现在看到了这个错误:

TypeError:错误:0606506D:数字信封 例程:EVP_DecryptFinal_ex:最终块长度错误
在 Decipheriv.Cipher.final (crypto.js:292:27)

这是来自 Gist 的解密代码(为方便起见,此处显示):

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);

【问题讨论】:

标签: node.js encryption openssl aes


【解决方案1】:

好的,所以在从 0.8 到 0.10 Crypto methods return Buffer objects by default, rather than binary-encoded strings的切换中对 Crypto 进行了更改@

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

这四行:

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

改为:

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

这对我有用,但我愿意接受其他建议。

【讨论】:

  • 老兄,你为我节省了很多时间。像魅力一样工作!
  • 我遇到了同样的错误,但我正在使用管道(将解密变量传递给文件上的pipe)以避免需要将整个文件放在内存中的问题。知道在这种情况下该怎么做吗?
  • 我们在 package.json 中没有“engines”属性的 Heroku 应用程序中遇到了这个问题。该版本已在部署时更新,但我们没有发现问题。谢谢!
  • @Michael 我在使用管道时也面临同样的问题......任何解决方案??
【解决方案2】:

正如您的回答所述,除非您指定编码,否则这些函数现在可以与缓冲区一起使用。也就是说,您最好完全避免使用binary 编码的字符串,并将所有内容都视为缓冲区,直到您严格需要某个字符串。这样,您还可以使用加密助手来处理非文本内容。

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】:

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

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

【讨论】:

    猜你喜欢
    • 2014-05-31
    • 2015-06-30
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多