我的印象是,基于密码的密钥派生函数的要点是每次都以相同的方式从密码生成密码安全的密钥流,因此可以依靠密码来生成密码中的加密密钥。带有Rfc2898DeriveBytes的PBKDF2为相同的输入产生不同的输出?
从我在线阅读的内容,包括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);
}
这个测试用例失败了,我找不到原因。我是否错误地使用了函数,或者我误解了它应该用于什么?
编辑:好了,测试方法是以上一个有缺陷的测试,因为我没有使用断言的集合形式。我认为AreEqual会在参数上调用.Equals,以及为了比较内容而实现的集合。
我有是,我认为同样的参数Rfc2898DeriveBytes正在产生对于相同的输入不同的输出,但输入是微妙的不同的问题:
我生成的16字节的盐,并存储在数据库中,但由于字段长度的原因,当盐被解密时,前16个字节是相同的(所以我认为它使用的是相同的信息),但是后面跟着另外48个字节的0,因此输入是不同。
啊,是的,正确的填充是问题。常见的错误,尽管在加密中,左填充是一个问题更常见;将整数编码为八位字符串(又名字节数组)通常会导致类似的问题。如果它让你感觉更快乐,我就会在常用的加密库,测试框架等中看到这种情况。 –