我使用带有密钥HelloWorld
的nodejs-aes256 https://www.npmjs.com/package/nodejs-aes256加密了单词apple
,输出为1ivBqj+nVPcHvZjQlx7Di0SoxV49bNpWtog=
然后我使用在线工具http://aesencryption.net/使用相同的密钥加密相同的单词,输出为LIxrc1buLeLLr9nJxtPhjHSYFVaceqsXiFamWiVWzYI=
乳清是不同的?
答案 0 :(得分:4)
首先," apple"不能成为AES-256的关键。它还不够长。 AES-256密钥必须精确为256位(32字节)。 "苹果"是,在可能的编码方式,5。所以这里已经存在问题。系统可能会为您填充零,但您不能依赖它。这不是AES键应该看起来像什么;他们需要32"有效随机"字节; "苹果"不是"有效随机。"
nodejs包表示它生成一个随机IV。这可能意味着它还对输出中的随机IV进行编码并期望它在输入中,并且确实是我们在代码中看到的:
ciphertext = Buffer.concat([iv, ciphertext, cipher.final()]);
假设PHP页面下面的源代码实际上与该工具有关,那么他们就称之为:
$this->setIV("");
可能会将某处转换为16个字节的零(这是一个非常不安全的IV)。
较短的答案是,绝对没有应用AES或编码输出的标准。您找到的绝大多数实现(包括这两个)都非常不安全,因为它们假设您知道如何添加它们所缺少的所有部分。例如,这两个实现都需要一个HMAC,因为它们使用的是CBC模式,但是它们都没有包含一个,如果你想要一个字符串像#34; apple"作为密码,您需要像PBKDF2这样的密钥派生函数将其转换为密钥。 (这就是你将像" apple"这样的字符串转换成某种东西"有效地随机。")任何安全实现都将与任何其他安全实现不兼容。没有广泛使用的标准格式也是安全的。
所有这一切,安全格式应始终导致两个加密具有不同的结果密文。 nodejs包通过包含随机IV来正确执行此操作,如果您多次运行它,您将得到不同的结果。这是防止某些类型攻击的功能。所以有不同的结果不应该是令人惊讶的。