2016-07-22 17 views
4

Ich wurde mit der Aufgabe beauftragt, eine neue Methode zur Berechnung von Passwort-Hashes zu schreiben, um die alte zu ersetzen, die wir noch nicht als ausreichend sicher empfinden. Vor einiger Zeit habe ich das Buch Security Driven .NET gelesen, in dem ich gelernt habe, dass es wichtig ist, einen Algorithmus mit einer konfigurierbaren Anzahl von Umdrehungen (im Gegensatz zu einem einfachen Hash) zu verwenden, und dass in .NET der empfohlene war PBKDF2 zur Passwortverwaltung genannt. Ich lese auch, dass es eine Verbesserung ist, wie ASP.NET mit Passwörtern umgeht, es wäre nett, wenn der resultierende in der Datenbank gespeicherte Hash kryptografisch an den Benutzer gebunden wäre (entweder Name oder ID), indem PBKDF2 zum Erstellen eines Masters verwendet wird Schlüssel, und verwenden Sie dann den Benutzernamen (oder die ID), um einen abgeleiteten Schlüssel mit HKDF zu erstellen. Aber das ist oberflächliches Wissen, dass ich aus einem Buch lese, auf das ich momentan keinen Zugriff habe. Ich kann also nicht überprüfen, ob mein Gedächtnis korrekt ist.Password Hashing mit PBKDF2 und HKDF in .NET

Außerdem habe ich die .NET DerivedBytes-APIs noch nicht verwendet, also könnte ich das falsch machen. Meine Frage ist also: Mache ich im folgenden Code richtig? Benutze ich die APIs richtig? Und ist diese Implementierung "ausreichend sicher"? Oder mache ich etwas falsch, was die Sicherheit komplett beseitigt?

protected override byte[] ComputeHash(string user, string salt, string password) 
{ 
    var userBytes = user.ToBytes(); 
​ 
    using (var pbkdf2 = new PBKDF2(MacFactories.HMACSHA512, password.ToBytes(), salt.ToBytes())) 
    { 
     var masterKey = pbkdf2.GetBytes(128); 
     using (var hkdf = new HKDF(MacFactories.HMACSHA512, masterKey, userBytes, userBytes)) 
     { 
      return hkdf.GetBytes(64); 
     } 
    } 
} 

Antwort

4

Sie haben die richtige Idee/Ansatz - hier eine etwas bessere Umsetzung ist:

byte[] ComputeHash(string user, string salt, string password) 
{ 
    using (var pbkdf2 = new PBKDF2(HMACFactories.HMACSHA512, password, salt.ToBytes())) 
    using (var hkdf = new HKDF(HMACFactories.HMACSHA512, pbkdf2.GetBytes(64), user.ToBytes())) 
     return hkdf.GetBytes(64); 
} 

Sie sollten für mehr Bytes als die Byte-Länge des zugrunde liegenden PRF (in Ihrem Fall nicht pbkdf2 fragen , SHA512, die 64 Bytes erzeugt).

Sie können hkdf Kontext als null verlassen, da Sie keine Notwendigkeit dafür zu haben scheinen.

Für andere, die sich vielleicht fragen, welche Bibliothek der obige Code verwendet - Inferno crypto.