Password Hash / Salt korrekt vergleichen (MD5, SHA256 , SHA512)

  • C#

    Password Hash / Salt korrekt vergleichen (MD5, SHA256 , SHA512)

    Hallo zusammen! :)

    Ich suche gerade verzweifelt einen Weg zu finden, den Passwort Hash/Salt für folgendes Fallbeispiel zu berechnen:

    Auf einem Linux System gibt es die Datei /etc/shadow. Die Zeilen dieser Datei beschreiben jeweils einen Benutzernamen mit Passwort der auf dem Linux System existiert. Als Beispiel gibt es für den Benutzer "csharp" mit dem Passwort "1337" folgende Zeile:

    csharp:$6$qVnvjWpk$DOUTmbC9ROZ6s1h0hCZTYWLFfVeUWDbz8f0EUFPEJEC2UKQV0gRiIfoGpnaA.8i4RCcrGpOEHEd9xrAUDpo3Y/:18337:0:99999:7:::

    Aufbau der Zeile

    • Der Text vor dem ersten Doppelpunkt beschreibt den Benutzernamen => Split(":")[0]
    • Das Zeichen hinter dem ersten "$" ist die Hash-Methode (MD5 => 1; SHA256 => 5; SHA512 => 6) => Split("$")[1]
    • Der Text hinter dem zweiten "$" ist der Salt => Split("$")[2]
    Das Problem ist nun, wie komme Ich auf den Hash-Salt Wert, um sagen zu können dass das Passwort korrekt ist oder nicht?
    Wenn Ich OpenSSL (leider nicht teil des Systemes!) den Salt eingebe, bekomme Ich ein Teil der Zeile raus. (Die -6 sagt aus, dass es sich um SHA512 handelt)

    Quellcode

    1. openssl passwd -6 -salt qVnvjWpk 1337
    2. >>> $6$qVnvjWpk$DOUTmbC9ROZ6s1h0hCZTYWLFfVeUWDbz8f0EUFPEJEC2UKQV0gRiIfoGpnaA.8i4RCcrGpOEHEd9xrAUDpo3Y/ <<<


    Bisher habe Ich folgenden Ansatz als Lösungskonzept (Die oben genannte Zeile aus der /etc/shadow wurde als Beispiel genommen)

    C#-Quellcode

    1. CheckCredentials("csharp", "1337");


    C#-Quellcode

    1. public static bool CheckCredentials(string username, string password) {
    2. string[] shadow = File.ReadAllLines("/etc/shadow");
    3. foreach(string entry in shadow) {
    4. // entry = csharp:$6$qVnvjWpk$DOUTmbC9ROZ6s1h0hCZTYWLFfVeUWDbz8f0EUFPEJEC2UKQV0gRiIfoGpnaA.8i4RCcrGpOEHEd9xrAUDpo3Y/:18337:0:99999:7:::
    5. if(entry.Split(":")[0] == username) {
    6. // hash = 6f0ac65fe01188660aad900bfe16c566ebf0e56c0a7d4a15bd831049108de80bd3a2fbf1a8b91662433a40458ec208a207cab073f190bd65b889e95e4fca8e09
    7. // $6 => SHA512
    8. string hash = HashSHA512(password);
    9. // salt = qVnvjWpk
    10. string salt = entry.Split("$")[2];
    11. // >>> Die eine Millionen Euro Frage: Stimmt das Passwort "1337"? <<<
    12. break;
    13. }
    14. throw new Exception($"User '{username}' was not found");
    15. }
    16. return false;
    17. }



    C#-Quellcode

    1. public static string HashSHA512(string input)
    2. {
    3. SHA512Managed crypt = new SHA512Managed();
    4. StringBuilder hash = new StringBuilder();
    5. byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(input));
    6. foreach (byte append in crypto)
    7. {
    8. hash.Append(append.ToString("x2"));
    9. }
    10. return hash.ToString();
    11. }