我使用带有密钥的HelloWorld
nodejs-aes256 https://www.npmjs.com/package/nodejs-aes256加密了单词然后我使用在线工具http://aesencryption.net/
使用相同的密钥加密了相同的单词输出是apple
1ivBqj+nVPcHvZjQlx7Di0SoxV49bNpWtog=
LIxrc1buLeLLr9nJxtPhjHSYFVaceqsXiFamWiVWzYI=
他们为什么不同?
我使用带有密钥的HelloWorld
nodejs-aes256 https://www.npmjs.com/package/nodejs-aes256加密了单词然后我使用在线工具http://aesencryption.net/
使用相同的密钥加密了相同的单词输出是apple
1ivBqj+nVPcHvZjQlx7Di0SoxV49bNpWtog=
LIxrc1buLeLLr9nJxtPhjHSYFVaceqsXiFamWiVWzYI=
他们为什么不同?
首先,“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 正确地做到了这一点,如果你多次运行它,你会得到不同的结果。这是一个可以防止某些类型的攻击的功能。所以有不同的结果应该不足为奇。