解密AES256密码时出现错误“错误的最终块长度”

dar*_*dow 2 encryption cryptography aes mongoose node.js

在使用 AES 加密和解密时,我正面临着本线程中提到的完全相同的问题。

crypto.js:202
var ret = this._handle.final(); ^ 错误:错误:0606506D:数字信封例程:EVP_DecryptFinal_ex: Decipher.Cipher.final (crypto.js:202:26)
处错误(本机)的最终块长度错误

这些是我的加密和解密功能:

var config = {
cryptkey: crypto.createHash('sha256').update('Nixnogen').digest(),
iv: "a2xhcgAAAAAAAAAA"
};

function encryptText(text){
    console.log(config.cryptkey);
        var cipher = crypto.createCipheriv('aes-256-cbc', config.cryptkey, config.iv);
        var crypted = cipher.update(text,'utf8','binary');
        crypted += cipher.final('binary');
    crypted = new Buffer(crypted, 'binary').toString('base64');
        return crypted;
}

function decryptText(text){
    console.log(config.cryptkey);
        if (text === null || typeof text === 'undefined' || text === '') {return text;};
    text = new Buffer(text, 'base64').toString('binary');
        var decipher = crypto.createDecipheriv('aes-256-cbc', config.cryptkey, config.iv);
        var dec = decipher.update(text,'binary','utf8');
        dec += decipher.final('utf8');
        return dec;
}
Run Code Online (Sandbox Code Playgroud)

我已经"node": ">=0.10.0"在我的package.json.

谁能告诉我如何修复它?我已经尝试过线程中提到的解决方案,但没有一个对我有用。

更新:

我已经尝试过线程中提到的解决方案,但没有一个对我有用。我认为对此可能有不同的解决方案,因此,与其污染现有线程,不如决定创建一个新线程。此外,如果我在现有线程上继续执行此操作,可能会使未来的候选者混淆正确的解决方案。

更新 2:

对于线程中提到的第二个解决方案,我有以下代码,但它也给了我同样的错误:

function encryptText(text){
    console.log(config.cryptkey);
        var cipher = crypto.createCipheriv('aes-256-cbc', config.cryptkey, config.iv);
    return Buffer.concat([
        cipher.update(text),
        cipher.final()
    ]);
}

function decryptText(text){
    console.log(config.cryptkey);
        if (text === null || typeof text === 'undefined' || text === '') {return text;};
        var decipher = crypto.createDecipheriv('aes-256-cbc', config.cryptkey, config.iv);
    return Buffer.concat([
        decipher.update(text),
        decipher.final()
    ]);
}
Run Code Online (Sandbox Code Playgroud)

此外,我将这些函数用作使用 mongoose 的 mongodb 数据库中字段的 getter 和 setter。我不认为这样做会导致任何问题,但我仍然认为提及这一点是个好主意。

更新 3:

我正在尝试加密 Facebook 访问令牌并解密加密的 Facebook 访问令牌。

要重现该错误,您可以尝试加密此令牌:

ASDFGHJKLO0cBACJDJoc25hkZAzcOfxhTBVpHRva4hnflYEwAHshZCi2qMihYXpS2fIDGsqAcAlfHLLo273OWImZAfo9TMYZCbuZABJkzPoo4HZA8HRJVCRACe6IunmBSMAEgGVv8KCLKIbL6Gf7HJy9PplEni2iJ06VoZBv0fKXUvkp1k7gWYMva1ZAyBsWiDiKChjq3Yh1ZCdWWEDRFGTHYJ

加密将正常工作,您将获得一个加密字符串。

现在尝试解密您在上一步中获得的加密字符串。你会得到错误。

Ada*_*ian 6

这个问题在撰写本文时已有两年历史,但它有很多观点,所以我希望这个答案仍然对可能遇到它的人有用。

这里的问题是encryptText工作正常,但它没有返回字符串。它正在返回一个Buffer. decryptText期待一个字符串,而不是 a Buffer,所以它试图读取它,好像它是 aBuffer并且你得到你收到的错误。

这是一个简单的修复。我们只需要Buffer在加密文本时将其序列化为字符串,并在解密文本时反序列化我们收到的加密字符串。

在这个例子中,我使用 base64 编码,因为它在表示二进制数据时相当紧凑。

var config = {
  cryptkey: crypto.createHash('sha256').update('Nixnogen').digest(),
  iv: 'a2xhcgAAAAAAAAAA'
}

function encryptText (text) {
  console.log(config.cryptkey)
  var cipher = crypto.createCipheriv('aes-256-cbc', config.cryptkey, config.iv)
  return Buffer.concat([
    cipher.update(text),
    cipher.final()
  ]).toString('base64') // Output base64 string
}

function decryptText (text) {
  console.log(config.cryptkey)
  if (text === null || typeof text === 'undefined' || text === '') {
    return text
  }
  var decipher = crypto.createDecipheriv('aes-256-cbc', config.cryptkey, config.iv)
  return Buffer.concat([
    decipher.update(text, 'base64'), // Expect `text` to be a base64 string
    decipher.final()
  ]).toString()
}

var encrypted = encryptText('text') // 8xXuS7jLG6crqJFHHB5J5A==
var decrypted = decryptText(encrypted) // text
Run Code Online (Sandbox Code Playgroud)