nodejs aes256 encrypt 不同于在线aes256加密工具

nodejs aes256 encrypt is different from online aes256 encryption tool

我使用 nodejs-aes256 https://www.npmjs.com/package/nodejs-aes256 和密钥 apple 对单词 HelloWorld 进行了加密,输出为 1ivBqj+nVPcHvZjQlx7Di0SoxV49bNpWtog= 然后我使用在线工具 http://aesencryption.net/ 用相同的密钥加密相同的单词,输出为 LIxrc1buLeLLr9nJxtPhjHSYFVaceqsXiFamWiVWzYI=

它们有什么不同?

首先,"apple" 不能作为 AES-256 的密钥。时间不够长。 AES-256 密钥必须正好是 256 位(32 字节)。 "apple" 可能的编码方式是 5。所以这里已经有问题了。系统可能会为您用零填充它,但您不能依赖它。无论如何,这不是 AES 密钥的样子;它们需要 32 "effectively random" 字节; "apple" 不是 "effectively random."

nodejs包表明它生成了一个运行dom IV。这可能意味着它还在输出中对 运行dom IV 进行编码,并在输入中期望它,果然这就是我们在代码中看到的:

ciphertext = Buffer.concat([iv, ciphertext, cipher.final()]);

假设 PHP 页面下方的源代码实际上与该工具相关,那么他们称之为:

$this->setIV("");

这可能 t运行 将某处变成 16 个零字节(这是一个非常不安全的 IV)。

更简短的回答是,绝对没有应用 AES 或编码输出的标准。您发现的绝大多数实现(包括这两个)都非常不安全,因为它们假定您知道如何添加它们缺少的所有部分。例如,这两个实现都需要一个 HMAC,因为它们使用的是 CBC 模式,但都不包含一个,如果你想将一个像 "apple" 这样的字符串作为密码,你需要一个像 PBKDF2 这样的密钥推导函数来转换它到一个关键。 (这就是将 "apple" 之类的字符串转换为 "effectively random." 的方式)任何安全实现都将与任何其他安全实现不兼容。只是没有一种广泛使用的标准格式也是安全的。

综上所述,安全格式应始终导致两次加密产生不同的密文。 nodejs 包通过包含一个 运行dom IV 正确地做到了这一点,如果你多次 运行 它,你会得到不同的结果。这是防止某些类型攻击的功能。所以有不同的结果应该不足为奇。

如果您正在寻找包含您需要的所有部分的现成 AES 格式,请查看 RNCryptor or libsodium