2013-07-17 9 views
21

In der Vergangenheit, wenn ich mit Passwörtern zu tun habe, habe ich immer ein Salz und ein Hash-Passwort getrennt in meinem Datenspeicher gespeichert. Heute habe ich versucht, einigen Legacy-Code zu aktualisieren, um einen RFC-2898-Hash-Wert zu verwenden. Ich bin auf die Crypto.Hash Methoden von System.Web.Helpers gestoßen. Es sieht so aus, als würden diese das meiste schwere Heben für mich erledigen. Es gibt GenerateSalt(), HashPassword() und VerifyHashedPassword() Methoden. Die Methoden HashPassword() und VerifyHashedPassword() nehmen keinen Salzwert an. Die MSDN-Dokumentation für HashPassword() Methode sagt:System.Web.Helpers.Crypto - Wo ist das Salz?

"Das Format des generierten Hash-Bytestreams ist {0x00, Salz, Unterschlüssel}, die Base-64 codiert ist, bevor es zurückgegeben wird."

Muss ich mich um ein Salz kümmern? Die Dokumentation scheint zu sagen, dass ein Salz automatisch generiert und im Basis-64-kodierten Wert gespeichert wird? Ist das richtig? Alles, was ich speichern muss, ist die von HashPassword() zurückgegebene Zeichenfolge?

Antwort

42

Antwort

Alle Passwörter müssen, um gesalzen werden, um sie sicher zu Hash. In diesem Fall haben Sie jedoch Recht. System.Web.Helpers.Crypto kümmert sich um die Erstellung eines Salzes für Sie. Sie müssen nicht erstellen. Es wird in der Zeichenfolge gespeichert, die von Crypto.HashPassword() zurückgegeben wird.

Beispiel

Alles, was Sie tun müssen, so etwas wie dieses.

using System.Web.Helpers; 

public void SavePassword(string unhashedPassword) 
{ 
    string hashedPassword = Crypto.HashPassword(unhashedPassword); 
    //Save hashedPassword somewhere that you can retrieve it again. 
    //Don't save unhashedPassword! Just let it go. 
} 

public bool CheckPassword(string unhashedPassword) 
{ 
    string savedHashedPassword = //get hashedPassword from where you saved it 

    return Crypto.VerifyHashedPassword(savedHashedPassword, unhashedPassword) 
} 

Weitere Informationen

  • Wenn Sie möchten, den Quellcode für die Crypto-Klasse sehen, dass es here sehen können.
  • Und here ist ein guter Blog über die Klasse und einige der Ideen dahinter.
+0

+1 aber wo ist die Blog-Post –

+0

Ich kann nicht vorstellen, wie es ein Salz erzeugt, aber Sie speichern nicht in der Datenbank für die nächste Überprüfung ? –

+5

@LeandroDeMelloFagundes Das Salz und das Hash-Passwort sind beide in der einzigen Zeichenfolge gespeichert, die von 'Crypto.HashPassword' zurückgegeben wird. –

0

wollte einfach diesen Beitrag teilen:

http://forums.asp.net/t/1842429.aspx?System+Web+Helpers+Crypto+HashPassword

Hallo,
Ich habe in System.Web.Helpers am neuen Crypto HashPassword und VerifyMethod Methode suchen.
Beide Methoden verwenden ein Salz, aber sie geben das Salz nicht nur den Hash zurück.
Benötige ich das Salz nicht, um es in der Datenbank zu speichern? Fehle ich etwas?
Danke,
Miguel

..

Sie das Salz erzeugen würde, wenn der Benutzer das Konto erstellt, und dann Sie es an das Passwort anhängen würde, bevor Sie HashPassword nennen . Sie würden dann speichern Sie das Salz und das Hash-Passwort in Ihrer Datenbank. Wenn Sie die Anmeldeinformationen validieren, lesen Sie einfach das Salz aus der Datenbank und hängen es an das Kennwort von der Anmeldung vor dem Aufruf von VerifyHashedPassword. BrockAllen

..

nicht sicher, ob ich es verstanden ... Weil in HashPassword ein Salz ist innerhalb der Methode erzeugt:

Miguel

// Method in Crypto class 
public static string HashPassword(string password) 
{ 
    if (password == null) 
    { 
     throw new ArgumentNullException("password"); 
    } 

    // Produce a version 0 (see comment above) password hash. 
    byte[] salt; 
    byte[] subkey; 
    using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount)) 
    { 
     salt = deriveBytes.Salt; 
     subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength); 
    } 

    byte[] outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength]; 
    Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize); 
    Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength); 
    return Convert.ToBase64String(outputBytes); 
} 

..

BrockAllen 11. September 2012 19.50

Ja, ignorieren, dass - es ist ein inneres Salz für die Rfc2898DeriveBytes und es aus dem Passwort abgeleitet ist, so dass es kein echtes Salz ist in der Kontext der Speicherung von Passwörtern, da es für das gleiche Passwort konsequent neu erstellt wird. Sie werden immer noch Ihr eigenes Salz unter der Passwort-Zeichenkette machen wollen. So etwas wie folgt aus:

public void CreateAccount(string username, string password) 
{ 
    var salt = Crypto.GenerateSalt(); 
    var saltedPassword = password + salt; 
    var hashedPassword = Crypto.HashPassword(saltedPassword); 
    CreateAccount(username, salt, hashedPassword); 
} 

public void Verify(string username, string password) 
{ 
    var salt = GetSaltForUserFromDatabase(username); 
    var hashedPassword = GetHashedPasswordForUserFromDatabase(username); 
    var saltedPassword = password + salt; 
    if (Crypto.VerifyHashedPassword(hashedPassword, saltedPassword)) 
    { 
     // valid password for this username 
    } 
} 

Dies ermöglicht Ihnen, Ihr Salz in der Datenbank zu speichern zusammen mit dem gesalzenen Passwort gehasht.

Zusätzliche Informationen über Passwort-Hashing mit Salz im allgemeinen von diesem Posten: https://crackstation.net/hashing-security.htm

Um ein Passwort zu speichern

  1. Generieren eines langen Zufalls Salz ein CSPRNG verwenden.
  2. Fügen Sie das Salz dem Kennwort voran und hashen Sie es mit einer standardmäßigen kryptographischen Hash-Funktion wie SHA256.
  3. Speichern Sie das Salz und den Hash im Datenbankeintrag des Benutzers.

Um ein Passwort

  1. das Salz des Benutzers abrufen und Hash aus der Datenbank zu validieren.
  2. Das Salz auf das angegebene Passwort vorgeben und mit der gleichen Hash-Funktion hashen.
  3. Vergleichen Sie den Hash des angegebenen Kennworts mit dem Hash aus der Datenbank. Wenn sie übereinstimmen, ist das Passwort korrekt. Ansonsten ist das Passwort falsch.

Source Code für Crypto Klasse:

http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Helpers/Crypto.cs

+2

Diese Antwort ist irreführend und veraltet. Sie müssen Ihr eigenes Salz nicht manuell erstellen. Brock Allen war unkorrekt darüber, dies tun zu müssen, und aktualisierte den Thread später mit diesem Kommentar: BrockAllen "Das Passwort muss nicht manuell gesedet werden - das wird bereits von der Crypto.HashPassword-API erledigt. Siehe diesen Beitrag: http://brockallen.com/2012/10/19/password-management-made-easy-in-asp-net-with-the-crypto-api/ – NickG