2012-08-31 11 views
7

Könnten Sie mir bitte sagen, ob die folgenden ein guter Weg ist sicher, ein Passwort-Hash in einer Datenbank gespeichert werden:Ist dies eine sichere Möglichkeit, ein Passwort zu hashen?

public string CreateStrongHash(string textToHash) { 

     byte[] salt =System.Text.Encoding.ASCII.GetBytes("TeStSaLt"); 

     Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(textToHash, salt, 1000); 
     var encryptor = SHA512.Create(); 
     var hash = encryptor.ComputeHash(k1.GetBytes(16)); 

     StringBuilder sb = new StringBuilder(); 
     for (int i = 0; i < hash.Length; i++) { 
      sb.Append(hash[i].ToString("x2")); 
     } 

     return sb.ToString(); 

    } 

Vielen Dank im Voraus.

+4

Idealerweise denke ich, Sie sollten ein anderes Salz pro Benutzer haben, und speichern Sie das in der Datenbank auch. – Bridge

+1

Tut mir leid, wenn ich ein bisschen zu dicht bin, aber wenn jemand Zugriff auf die Datenbank erhält, macht es das Speichern des Salzes nicht einfacher für jemanden, die Verschlüsselung zu knacken? – ScubaSteve2012

+0

@ ScubaSteve2012 Das Salz verhindert vorberechnete Hash-Angriffe ("Rainbow-Tabellen"). Da die Passwörter gesalzen sind, wäre Ihre Rainbow-Tabelle nutzlos, um die ursprünglichen Passwörter herauszufinden. Du müsstest eine neue Rainbow-Tabelle erstellen, indem du diesen Hash verwendest, der ein Brute-Force-Angriff ist. – Oleksi

Antwort

7

Sie verwenden PBKDF2-SHA1, das ist anständig, aber nicht großartig. Bcrypt ist ein bisschen besser und Scrypt ist noch stärker. Aber da .net bereits eine eingebaute PBKDF2-Implementierung enthält, ist das eine akzeptable Wahl.

Ihr größter Fehler ist, dass Sie nicht den Sinn eines Salzes bekommen haben. Ein Salz sollte für jeden Benutzer eindeutig sein. Es ist üblich, einfach einen zufälligen Wert von mindestens 64 Bit zu erstellen. Speichern Sie es zusammen mit dem Hash in der Datenbank.

Wenn Sie möchten, können Sie das Salz in zwei Teile teilen. Ein in der Datenbank neben dem Benutzer gespeicherter, der für jeden unterschiedlich ist, und ein gemeinsamer Teil, der woanders gespeichert ist. Dies gewinnt die Vorteile beider.

Ich empfehle auch einen höheren Workfactor als 1000. Finden Sie heraus, welche Leistung akzeptabel ist und passen Sie sie entsprechend an. Ich würde nicht unter 10000 gehen, und in manchen Situationen (Festplattenverschlüsselung) ist auch eine Million akzeptabel.

+0

Danke für Ihre Hilfe. – ScubaSteve2012

+0

Wenn der Salt-Wert als solcher in der Datenbank gespeichert wird, ist es sehr hilfreich, eine Kollision zu vermeiden. Sein wichtigstes Dienstprogramm in diesem Fall ist es, zu verhindern, dass ein Angreifer durch Inspektion feststellt, dass zwei Benutzer das gleiche Passwort haben. Es wäre besser, Daten zu verwenden, die nicht ausdrücklich als "Salz" gekennzeichnet sind, oder besser, die nicht im selben Datenspeicher enthalten sind. Der Angreifer muss dann nicht nur die Datenbank mit den Hashes, sondern auch die Codebasis und/oder einen zusätzlichen Datenspeicher kompromittieren, um zu bestimmen, was als Salz zu verwenden ist und wie. – KeithS

+0

@KeithS Ich habe das Wort Kollision nie erwähnt, weil Kollisionen hier irrelevant sind. Der Hauptpunkt eines Salzes ist einzigartig und verhindert so Angriffe mit mehreren Zielen. Das Hinzufügen eines Geheimnisses, das an verschiedenen Orten gespeichert ist, ist ein nettes Extra, aber nicht der Hauptpunkt eines Salzes. – CodesInChaos

5

Es kann verbessert werden. Zuerst sollten Sie stattdessen bcrypt verwenden. Herkömmliche Hashes wie SHA-512 lassen sich heutzutage mit GPUs ziemlich leicht durchbrechen. Das Problem ist, dass diese Hashes auf Geschwindigkeit ausgelegt sind, und dies ist das Gegenteil von dem, was Sie in einem Passwort-Hash wollen. Bcrypt ist ein Beispiel für einen adaptiven Hashalgorithmus. Es kann so konfiguriert werden, dass es eine "lange" Zeit benötigt (aber immer noch keine Performance-Probleme in Ihrem System verursacht), um Brute-Forcing zu erschweren.

Sie möchten auch die Salze für jeden Benutzer einzigartig machen.

Weitere Informationen zum sicheren Hacken von Kennwörtern finden Sie unter this question.

+3

Er benutzt PBKDF2, was etwas schlechter ist als bcrypt, aber immer noch eine der empfohlenen Funktionen. – CodesInChaos

+0

SHA-512 ist buchstäblich "gut genug für Regierungsarbeit"; es wird als kryptographisch stark angesehen und es gibt keine bekannte "Abkürzung", die die Komplexität des Findens der Lösung verringert. Die Tatsache, dass jedes Problem "schneller" gelöst werden kann, indem man genug Hardware darauf wirft, ist irrelevant; Sie müssten 5 versuchen.2 × 10^72 Werte vor einer Wahrscheinlichkeit von 1 zu * 1 Milliarde *, mit einem zuvor erzeugten Hash zu kollidieren. – KeithS

+1

@KeithS Plain SHA-512 ist nicht gut genug für Anwendungen wie Passwort-Hashing, weil es zu schnell ist. Beim Password Hashing verwenden Sie bewusst teure Funktionen, um die fehlende Entropie in einem Passwort zu kompensieren. | PBKFDF2 mit SHA-512 ist dagegen in Ordnung. – CodesInChaos

Verwandte Themen