Question

I was under the impression that the point of password based key-derivation functions was to generate a cryptographically secure key stream from a password in the same way every time, so they can be relied upon for producing encryption keys from passwords.

From what I've read online, including stack overflow, this seems to be the intended use.

So when I was generating different outputs for what I thought were the same inputs I assumed I was using it wrong. To test this, I wrote a test case for Rfc2898DeriveBytes that uses it in the way the documentation suggests.

[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);
}

This test case is failing, and I can't figure out why. Am I mis-using the function, or am I misunderstanding what it should be used for?

Edit: Ok, the test method above was a flawed test because I wasn't using the Collection form of the assertion. I thought that AreEqual would call .Equals on arguments, and that for collections that would be implemented to compare contents.

The problem I was having was that I thought the same arguments to Rfc2898DeriveBytes was producing different output for the same input, but the input was subtly different:

I generated a 16 byte salt and stored it in the database, but because of the field length, when the salt was retrieved for decryption, the first 16 bytes were the same (so I thought it was using the same information) but these were followed by another 48 bytes of 0s, and the inputs were therefore different.

Was it helpful?

Solution

MSTest's Assert.AreEqual will normally do reference equality comparison on collections (unless it is a custom collection that overrides Equals), which is not usually what you want. Try using CollectionAssert.AreEqual.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top