带有Rfc2898DeriveBytes的PBKDF2为相同的输入产生不同的输出?

时间:2013-08-05 15:59:18

标签: c# .net cryptography pbkdf2

我的印象是,基于密码的密钥派生函数的关键是每次都以相同的方式从密码生成加密安全密钥流,因此可以依赖它们从密码生成加密密钥。 / p>

从我在网上看到的内容,包括stack overflow,这似乎是预期用途。

因此,当我为我认为相同的输入生成不同的输出时,我认为我错误地使用了它。为了测试这个,我为Rfc2898DeriveBytes编写了一个测试用例,它以文档建议的方式使用它。

[TestMethod]
public void PBKDF2_Works() {
    var salt = new byte[] { 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0D, 0x15 };
    var password = "password";
    var iterations = 1000;
    var len = 48;

    var gen1 = new Rfc2898DeriveBytes(password, salt, iterations);
    var gen2 = new Rfc2898DeriveBytes(password, salt, iterations);

    var bytes1 = gen1.GetBytes(len);
    var bytes2 = gen2.GetBytes(len);
    Assert.AreEqual(bytes1, bytes2);
}

此测试用例失败,我无法弄清楚原因。我错误地使用了这个功能,还是我误解了它应该用于什么?

编辑:好的,上面的测试方法是一个有缺陷的测试,因为我没有使用断言的Collection形式。我认为AreEqual会在参数上调用.Equals,而对于那些将用于比较内容的集合。

我遇到的问题是我认为Rfc2898DeriveBytes的相同参数为同一输入产生不同的输出,但输入略有不同:

我生成了一个16字节的盐并将其存储在数据库中,但由于字段长度,当检索到盐进行解密时,前16个字节是相同的(所以我认为它使用了相同的信息)但是其次是另外48个字节的0,因此输入不同。

1 个答案:

答案 0 :(得分:3)

MSTest的Assert.AreEqual通常会对集合进行引用相等性比较(除非它是覆盖Equals的自定义集合),这通常不是您想要的。尝试使用CollectionAssert.AreEqual