tags:

views:

115

answers:

5

I'm trying to verify someone's password when logging in.

I take the entered password and retrieve the users saved hashed password and password salt.

Then I hash the entered password with the saved salt to see if it's equal to the saved password.

However, even though the byte[] storedPassword is exactly like the byte[] enteredPassword, it doesn't return true in a bool and therefore doesn't verify the user. Why is that?

public static bool VerifyPassword(byte[] newPassword, byte[] storedPassword, byte[] storedSalt)
    {
        byte[] password = CreateHashedPassword(newPassword, storedSalt);

        if (!password.Equals(storedPassword))
            return false;

        return true;
    }
+3  A: 

Equals does not byte compare the two byte[] arrays. You have to compare each byte in the two arrays yourself.

logicnp
+2  A: 

You have to iterate over the elements of an array to see if they are the same. Using the .Equals() method only tells you if two variables reference the same array.

        for (int i = 0; i < password.Length; i++)
            if (password[i] != storedPassword[i])
                return false;
        return true;
Gabe
Before this code, I would compare the length of password and storedPassword. If storedPassword is smaller than password you can read past the end of the array. On the flip side, if password is shorter, it is only comparing the first few bytes. If you can get the password to be a shorter size, it might be possible to match with a prefix of the stored password. Jacob
TheJacobTaylor
Generally speaking, password hash algorithms always produce output of the same number of bytes. For example, an MD5 hash is always 16 bytes, so there's no need to check the length of the hashes.
Gabe
+6  A: 

You should compare each byte of your arrays, you can make a simple loop, or use the SequenceEqual Linq Extension method if available:

public static bool VerifyPassword(byte[] newPassword, byte[] storedPassword,
                                  byte[] storedSalt)
{
    byte[] password = CreateHashedPassword(newPassword, storedSalt);

    return password.SequenceEqual(storedPassword);
}
CMS
A: 

The System.Array.Equals method appears to test only for object identity, just like object.Equals.

You have to write a loop and compare the elements yourself.

Scott Smith
A: 

Array.Equals is like object.Equals, it tests for instance equality, not for "value" equality.

You need something like:

public static boolean ByteArrayEquals(byte[] a, byte[] b) {
  if (a.Length != b.Length)
    return false;
  for (int i = 0; i < a.Length; i++)
  {
      if (a[i] != b[i])
        return false;
  }
  return true;
}
mjv