C# Hash Werte vergleichen?
Hallo, ich möchte bei einem Login das Passwort hashen. Wenn man sich eingeloggt hat, kann man neue Benutzer hinzufügen. DIe neuen Benutzer werden dann auch gehasht und beim einloggen soll geprüft werden, ob der Hash Wert vom hinzufügen des Benutzers mit dem Hash Wert beim einloggen übereinstimmt. Wie mache ich das? In meinem BenutzerDialog(dort werden die Benutzer erstellt) wird beim Erstellen_Clickeine Hush Methode aufgerufen.
public Benutzer _selectedBenutzer;
public void HashPassword() { PasswordWithSaltHasher pwHasher = new PasswordWithSaltHasher(); HashWithSaltResult hashResultSha512 = pwHasher.HashWithSalt("ultra_safe_P455w0rD", 64, SHA512.Create()); _selectedBenutzer.Passwort = hashResultSha512.Salt; _selectedBenutzer.Passwort = hashResultSha512.Digest; }
Wie vergleiche ich den Hash Wert vom Benutzer hinzufügen(BenutzerDialog) mit dem vom Login?
Will dann eine If-Anweisung in der Art schreiben(diese If-Anweisung ist dann im Login Button):
//If(hashwert == benutzerDialog.hashwert)
//{
// MessageBox.Show("Die Hash Werte stimmen überein-");
//}
//else
//{
// MessageBox.Show("DIe Hash Werte stimmen nicht überein");
//}
2 Antworten
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.
Sorry, es muss natürlich bool heißen, statt boolean, wir sind ja hier in C# und nicht in Java. ;-)
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