0

我使用带有密钥的HelloWorldnodejs-aes256 https://www.npmjs.com/package/nodejs-aes256加密了单词然后我使用在线工具http://aesencryption.net/ 使用相同的密钥加密了相同的单词输出是apple1ivBqj+nVPcHvZjQlx7Di0SoxV49bNpWtog=LIxrc1buLeLLr9nJxtPhjHSYFVaceqsXiFamWiVWzYI=

他们为什么不同?

4

1 回答 1

4

首先,“apple”不能是 AES-256 的密钥。时间不够长。AES-256 密钥必须是 256 位(32 字节)。“apple”在可能的编码方式中是 5。所以这里已经有问题了。系统可能会为您填充零,但您不能依赖它。无论如何,这不是 AES 密钥的样子;它们需要是 32 个“有效随机”字节;“苹果”不是“有效随机的”。

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

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

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

$this->setIV("");

这可能在某处转换为 16 个字节的零(这是一个非常不安全的 IV)。

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

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

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

于 2016-12-29T23:21:32.147 回答