C# Hash Werte vergleichen?

2 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Man muss hier leider ein bisschen rätselraten, aber ich vermute, Du hast den Code von hier.

https://dotnetcodr.com/2016/10/17/how-to-hash-passwords-with-a-salt-in-net/

Dort wird das Passwort mit einem zufälligen Salt gehasht und anschließend sowohl Salt, als auch Hashwert in einer Klasse HashWithSalt gespeichert.

Ich würde noch die beiden Zeilen in der Methode PasswordWithSaltHasher.HashWithSalt(...) umdrehen.

Statt ...

passwordWithSaltBytes.AddRange(passwordAsBytes);
passwordWithSaltBytes.AddRange(saltBytes);

... würde ich also folgendes tun ...

passwordWithSaltBytes.AddRange(saltBytes);
passwordWithSaltBytes.AddRange(passwordAsBytes);

... denn normalerweise stellt man das Salt voran.

Die Verifikation würde dann wie folgt funktionieren.

public boolean VerifyHashWithSalt(string password, HashWithSaltResult saltedHash, HashAlgorithm algorithm) {
   string hashString = saltedHash.Digest;
   string saltString = saltedHash.Salt;
   byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password);
   byte[] hashBytes = System.Convert.FromBase64String(hashString);
   byte[] saltBytes = System.Convert.FromBase64String(saltString);
   int saltAndPasswordLength = saltBytes.Length + passwordBytes.Length;
   byte[] saltAndPasswordBytes = new byte[saltAndPasswordLength];
   int saltLength = saltBytes.Length;
   saltBytes.CopyTo(saltAndPasswordBytes, 0);
   passwordBytes.CopyTo(saltAndPasswordBytes, saltLength);
   byte[] hash = algorithm.ComputeHash(saltAndPasswordBytes);

   /*
    * Hashes of unequal length cannot be equal.
    */
   if (hash.Length != hashBytes.Length)
      return false;
   else {
      boolean equal = true;

      /*
       * Verify that each of the bytes is equal.
       */
      for (int i = 0; i < hash.Length; i++)
         if (hash[i] != hashBytes[i])
            equal = false;

      return equal;
   }

}

Die Methode bekommt ein Passwort, einen gesalzenen Hashwert und ein Hashverfahren übergeben.

Die Hashwerte sind als Byte-Arrays repräsentiert. Die Methode übersetzt alles in Byte-Arrays (Passwort per Charset-Encoding, Salt und Hashwert per Base64), konkateniert anschließend Salz und Passwort und wendet darauf die Hashfunktion an.

Dann vergleicht es den ermittelten Hashwert zu demjenigen, welcher in der HashWithSaltResult-Klasse übergeben wurde. Hierzu vergleicht es zunächst die Längen der Hashwerte. Sind sie unterschiedlich, können die Hashwerte schonmal nicht übereinstimmen. Stimmen die Längen überein, vergleicht die Methode schließlich jedes der Bytes in den beiden Arrays. Sobald eine Abweichung gefunden wird, ist der Hashwert ungleich. Wird keine Abweichung gefunden, stimmen die Hashwerte überein.


NoHumanBeing  25.04.2018, 12:13

Sorry, es muss natürlich bool heißen, statt boolean, wir sind ja hier in C# und nicht in Java. ;-)

1
NoHumanBeing  04.05.2018, 00:46

Vielen Dank für den Stern! :-)

0

Bitte den Code formattieren...

Was ist die Klasse HashWithSaltResult, also wie ist diese aufgebaut?

Du kannst in dieser Klasse den == Operator überschreiben und dann einfach hash1 == hash2 abfragen.

https://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx