2010-02-26 10 views
7

Próbuję sprawdzić czyjeś hasło podczas logowania.2 równe byte [] nie zwróci true

Biorę wprowadzone hasło i pobierać użytkownicy zapisany zaszyfrowany hasłem i hasło soli.

Następnie haszuję wprowadzone hasło z zapisaną solą, aby sprawdzić, czy jest ona równa zapisanemu hasłu.

Mimo że bajt [] storedPassword jest dokładnie taki sam, jak wpisane hasło byte [], nie zwraca ono wartości true w bool i dlatego nie weryfikuje użytkownika. Dlaczego?

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

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

     return true; 
    } 

Odpowiedz

3

Równa się nie bajt porównać dwóch tablic bajtowych []. Musisz sam porównać każdy bajt w dwóch tablicach.

2

Musisz powtórzyć elementy tablicy, aby zobaczyć, czy są one takie same. Korzystanie z metody .Equals() powie ci tylko, czy dwie zmienne odnoszą się do tej samej tablicy.

 for (int i = 0; i < password.Length; i++) 
      if (password[i] != storedPassword[i]) 
       return false; 
     return true; 
+0

Przed tym kodem, chciałbym porównać długość hasła i storedPassword. Jeśli storedPassword jest mniejsze niż hasło, możesz odczytać poza końcem tablicy. Z drugiej strony, jeśli hasło jest krótsze, porównuje tylko kilka pierwszych bajtów. Jeśli możesz uzyskać hasło o mniejszym rozmiarze, możliwe jest dopasowanie z prefiksem zapisanego hasła. Jacob – TheJacobTaylor

+0

Ogólnie rzecz biorąc, algorytmy mieszania haseł zawsze generują wyjście o tej samej liczbie bajtów. Na przykład skrót MD5 ma zawsze 16 bajtów, więc nie ma potrzeby sprawdzania długości skrótów. – Gabe

13

Należy porównać każdy bajt swoich tablicach, można zrobić prostą pętlę, lub zastosować metodę, jeśli dostępne SequenceEqual Linq rozszerzeń:

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

    return password.SequenceEqual(storedPassword); 
} 
0

Sposób System.Array.Equals pojawia przetestować tylko dla tożsamości obiektu, podobnie jak object.Equals.

Musisz napisać pętlę i porównać elementy samodzielnie.

0

Array.Equals jest jak object.Equals, testuje na przykład równość, a nie dla "równości" wartości.

Trzeba coś takiego:

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