使用node.js解密AES256将返回错误的最终块长度

使用这个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); 

好的,所以在从0.8到0.10的转换中,Crypto发生了变化。Crypto方法默认返回Buffer对象,而不是二进制编码的string

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

这四行:

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

这工作对我来说,但我打开其他build议。

如您的答案所述,除非您指定编码,否则这些函数现在可以与缓冲区一起使用。 也就是说,最好避免使用binary编码的string,并把所有的东西都当作缓冲区,直到你严格需要一个string。 这样你也可以使用你的encryption助手来处理非文本内容。

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

我的问题是,我传递给我的解密函数的string是空的。 我build立一个空string的检查,我没有再收到消息。

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