我正在使用由Node.js中的本机“crypto”模块实现的AES 256。目前正在尝试验证加密明文的解密,一个任意字符串(见下文)。根据我的理解,我最好选择一个随机的初始化向量,我使用crypto.randomBytes(16)
做了 - 证据表明(文档说不多)它需要是128位。我显然也需要CBC模式,这是有道理的,因为我的明文通常是任意长度的。我也不需要PBKDF2或类似的东西,因为我自己选择自己的密钥,这根本不是密码。
我已经设法“排序”使事情有效,但解密的密文在前16个字节处出现乱码。我的预感告诉我这与填充,IV或两者有关。我不确定为什么我应该为Decipher
选择IV,但无论如何,只有部分恢复的明文与原始文本匹配,我不知道为什么。
var key = fs.readFileSync("/root/key"); // 256 bit data 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.");
排序plaintext.equals(decrypt(encrypt(plaintext)))
的断言失败,类似的断言如plaintext.toString("utf8") == decrypt(encrypt(plaintext)).toString("utf8")
也是如此。目视检查恢复的明文内容与原始明文也表明在恢复的明文的前128位有不同的(错误的)数据。
这可能与我在解密阶段使用IV的误解或使用两个不同的随机IV的事实有关。
我做错了什么,更重要的是我没有用AES和CBC模式得到什么,没有前进和解决关于链接分组密码的所有内容?
我也尝试过使用数据类型 - 使用普通的UTF-8字符串而不是Buffer
用于纯文本和密文,但这段代码看起来最短,实际上至少成功解密,而有些其他尝试让我“解密”错误。
答案 0 :(得分:4)
加密和解密的IV必须相同。这通常通过将随机生成的(和未加密的)IV加到密文前面来实现。对于CBC,IV总是与块大小相同 - 总是16个字节 - 要解密,首先从前16个字节中检索IV,然后解密其余的。