如何修复AES解密密文头部的“垃圾”?

amn*_*amn 6 cryptography aes node.js

我正在使用由cryptoNode.js 的一部分模块实现的 AES 256 ,以评估我是否可以将它用于我计划作为我正在设计的应用程序的一部分的特定数据保护功能。

我正在尝试验证一些加密的任意明文的解密,但我无法使原始明文和解密结果匹配,这意味着我的加密、解密或两者都有问题。

据我所知,我最好选择一个随机初始化向量 (IV),我确实使用了它crypto.randomBytes(16)——证据表明(文档没有说太多)它需要是 128 位。我显然也需要 CBC 模式,这是有道理的,因为我的用例要求明文具有任意长度。我也不需要 PBKDF2 或任何类似的东西,因为我自己选择自己的密钥,这根本与密码无关。

现在,其中一些似乎可以正常工作,但是我从解密中获得的明文的前 16 个字节是“乱码”。预感告诉我这与填充、IV 或两者有关。我不确定为什么我应该选择 IV,Decipher但无论如何,只有部分解密的明文与原始文本匹配,我不知道为什么。

用代码解释:

var key = fs.readFileSync("/root/key"); // 256 bits worth of key from a file

function encrypt(plaintext) {
    var cipher = crypto.createCipheriv("aes-256-cbc", key, crypto.randomBytes(16));
    return Buffer.concat([ cipher.update(plaintext), cipher.final() ]);
}

function decrypt(ciphertext) {
    var decipher = crypto.createDecipheriv("aes-256-cbc", key, crypto.randomBytes(16));
    return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
}

var plaintext = new Buffer("Quick brown fox jumps over the lazy dog.");
Run Code Online (Sandbox Code Playgroud)

评估plaintext.equals(decrypt(encrypt(plaintext)))收益false,也是如此plaintext.toString("utf8") == decrypt(encrypt(plaintext)).toString("utf8")。如前所述,解密明文与原始明文的目视检查表明在恢复(解密)明文的前 128 位中存在不同(错误)的数据。

这可能与我对在解密阶段使用 IV 的误解有关,或者与使用两个不同的随机 IV的事实有关。

我做错了什么,更重要的是我没有得到 AES 和 CBC 模式(如果有的话),而我不必了解链接块密码的所有内容?

我还尝试处理所涉及的数据类型——使用纯 UTF-8 字符串而不是Buffer纯文本和密文,但我上面的代码看起来最短,实际上至少成功解密(随后我后来对结果的断言失败了) ,而其他一些尝试让我从底层解密程序中得到了一个实际的“解密错误”错误。

Maa*_*wes 7

加密和解密的 IV 需要相同。这通常是通过将随机生成(和未加密)的 IV 添加到密文中来实现的。对于 CBC,IV 的大小始终与块大小相同 - 始终为 16 个字节 - 解密首先从前 16 个字节中检索 IV,然后解密其余部分。