Frage

Was ist Ihre bevorzugte Methode/Datentyp zum Speichern von Kennwörtern in einer Datenbank (vorzugsweise SQL Server 2005). Die Art und Weise, wie ich es in mehreren unserer Anwendungen gemacht habe, besteht darin, zuerst die .NET -Verschlüsselungsbibliotheken zu verwenden und dann in der Datenbank als Binärdatei zu speichern (16). Ist dies die bevorzugte Methode oder sollte ich einen anderen Datentyp verwenden oder mehr Platz als 16 zuweisen?

War es hilfreich?

Lösung

Ich speichere das gesalzene Hash -Äquivalent des Kennworts in der Datenbank und niemals das Passwort selbst und vergleichen Sie dann immer den Hash mit dem generierten, was der Benutzer übergeben hat.

Es ist zu gefährlich, jemals die buchstäblichen Passwortdaten überall zu speichern. Dies macht die Wiederherstellung unmöglich, aber wenn jemand ein Passwort vergisst oder verliert, können Sie einige Überprüfungen durchführen und ein neues Passwort erstellen.

Andere Tipps

Die bevorzugte Methode: Speichern Sie niemals Passwörter in Ihrer DB. Nur Hashes davon. Salz zum Geschmack hinzufügen.

Ich mache das Gleiche, was du beschrieben hast, außer es wird als Zeichenfolge gespeichert. I Base64 codieren den verschlüsselten Binärwert. Die Menge an Platz zur Zuweisung hängt vom Verschlüsselungsalgorithmus/der Verschlüsselungsstärke ab.

Ich denke, Sie machen es richtig (da Sie a verwenden Salz).

  1. Speichern Sie den Hash des Salzenpassworts wie Bcrypt (Nounce+PWD). Möglicherweise bevorzugen Sie Bcrypt gegenüber SHA1 oder MD5, da es als CPU-intensiv abgestimmt werden kann, wodurch ein Brute-Force-Angriff viel länger wird.
  2. Fügen Sie das Anmeldeformular nach wenigen Anmeldemangel eine Captcha hinzu (um die Angriffe zwischen Brute auf die Force-Force zu vermeiden).
  3. Wenn Ihre Bewerbung einen Link "Mein Passwort vergessen" hat, stellen Sie sicher von einigen persönlichen Daten, wie zum Beispiel das Geburtsdatum des Benutzers). Wenn Ihre Anwendung dem Benutzer ermöglicht, ein neues Kennwort zu definieren, stellen Sie sicher, dass der Benutzer das aktuelle Kennwort bestätigt.
  4. und sichern natürlich das Anmeldeformular (normalerweise mit HTTPS) und die Server selbst sichern

Mit diesen Maßnahmen sind die Passwörter Ihres Benutzers ziemlich gut geschützt gegen:

  1. => Offline -Wörterbuchangriffe
  2. => Live -Wörterbuchangriffe
  3. => Ablehnung von Serviceangriffen
  4. => Alle möglichen Angriffe!

Da das Ergebnis einer Hash-Funktion eine Reihe von Byte im Bereich von 0 bis 255 (oder -128 bis 127) ist, ist das Speichern als Rohbinärfeld am sinnvollsten sinnvoll , wie es die kompakteste Darstellung ist und keine zusätzlichen Codierungs- und Dekodierungsschritte erfordert.

Einige Datenbanken oder Treiber haben keine große Unterstützung für binäre Datentypen, oder manchmal sind Entwickler mit ihnen einfach nicht vertraut, um sich wohl zu fühlen. In diesem Fall ist die Verwendung einer Binär-Text-Codierung wie Base-64 oder Base-85 und die Speicherung des resultierenden Textes in einem Zeichenfeld akzeptabel.

Die Größe des erforderlichen Feldes wird durch die von Ihnen verwendete Hash -Funktion bestimmt. MD5 gibt immer 16 Bytes aus, SHA-1 gibt immer 20 Bytes aus. Sobald Sie eine Hash -Funktion ausgewählt haben, bleiben Sie normalerweise daran fest, da Änderungen ein Zurücksetzen aller vorhandenen Passwörter erforderlich sind. Wenn Sie also ein Feld mit variabler Größe verwenden, kauft Ihnen nichts.


In Bezug auf die "beste" Art, das Hashing auszuführen, habe ich versucht, viele Antworten auf andere Fragen zu diesem Thema zu geben:

Ich benutze den SHA -Hash des Benutzernamens, einen GUID in der Webkonfiguration und das als VARCHAR (40) gespeicherte Passwort. Wenn sie Force / Dictionary brutal wollen, müssen sie den Webserver auch für die Richtlinie hacken. Der Benutzername bricht, wenn sie eine Regenbogentabelle in der gesamten Datenbank erstellen, wenn sie das Passwort finden. Wenn ein Benutzer seinen Benutzernamen ändern möchte, setze ich das Passwort gleichzeitig zurück.

System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(
    username.ToLower().Trim(),
    ConfigurationManager.AppSettings("salt"),
    password
);

Ein einfacher Hash des Passworts oder sogar (Salz + Passwort) ist im Allgemeinen nicht angemessen.

sehen:

http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to- kennen-about-secure-password-schemes/

und

http://gom-jabbar.org/articles/2008/12/03/why-you-hould-use-suse-bcrypt-t-stor-your-passwords

Beide empfehlen die Bcrypt -Algorithmen. Kostenlose Implementierungen finden Sie online für die meisten beliebten Sprachen.

Sie können mehrere Hashes in Ihrer Datenbank verwenden, es erfordert nur ein wenig zusätzliche Anstrengung. Es lohnt sich jedoch, wenn Sie der Meinung sind, dass es die aus entfernte Chance gibt, dass Sie in Zukunft zusätzliche Formate unterstützen müssen. Ich werde oft Passworteinträge wie verwenden

{Hashid} $ {Salt} $ {Hashed -Passwort}

Wo "Hashid" nur eine Nummer ist, die ich intern benutze, um zu erkennen, dass ich Sha1 mit einem bestimmten Hash -Muster verwende; "Salz" ist ein Basis64-kodierter Zufallssalz; Und "Hashed Password" ist ein Basis64-kodierter Hash. Wenn Sie Hashes migrieren müssen, können Sie Personen mit einem alten Passwortformat abfangen und das Kennwort beim nächsten Anmelden ändern.

Wie andere erwähnt haben, möchten Sie mit Ihren Hashes vorsichtig sein, da es einfach ist, etwas zu tun, das nicht wirklich sicher ist, z. B. H (Salz, Passwort) ist weitaus schwächer als H (Passwort, Salz), aber gleichzeitig möchten Sie möchten Bildern Sie den Aufwand mit dem Wert des Site -Inhalts. Ich benutze oft H (H (Passwort, Salz), Passwort).

Schließlich sind die Kosten für die Verwendung von Base64-kodierten Kennwörtern im Vergleich zu den Vorteilen, die verschiedene Tools verwenden können, die Textdaten erwarten. Ja, sie sollten flexibler sein, aber sind Sie bereit, Ihrem Chef zu sagen, dass er sein Lieblings -Drittanbieter nicht verwenden kann, weil Sie ein paar Bytes pro Platte sparen möchten? :-)

Bearbeitet, um einen weiteren Kommentar hinzuzufügen: Wenn ich vorschlägt, einen Algorithmus absichtlich zu verwenden, der sogar ein 1/10 eines zweiten Hashing jedes Passworts verbrannte, hätte ich das Glück, nur aus dem Büro meines Chefs auszulachen. (Nicht so viel Glück? Er würde bei meiner nächsten jährlichen Bewertung etwas aufschreiben, um zu besprechen.) Wenn Sie diese Zeit verbrennen, ist es kein Problem, wenn Sie Dutzende oder sogar Hunderte von Benutzern haben. Wenn Sie 100.000 Benutzer drücken, haben Sie normalerweise mehrere Personen, die sich gleichzeitig anmelden. Sie brauchen etwas schnelles und Starkes, nicht langsam und starkes. "Aber was ist mit den Kreditkarteninformationen?" ist bestenfalls unaufrichtig, da gespeicherte Kreditkarteninformationen nicht in der Nähe Ihrer regulären Datenbank sein sollten und ohnehin von der Anwendung verschlüsselt werden, nicht von einzelnen Benutzern.

Wenn Sie mit ASP.NET arbeiten, können Sie die integrierte in der Mitgliedschafts -API verwenden.

Es unterstützt viele Arten von Speicheroptionen. Ein Way Hash, zwei Wege Verschlüsselung, Md5 + Salz. http://www.asp.net/learn/security Für mehr Information.

Wenn Sie nichts zu schickes brauchen, ist dies für Websites großartig.

Wenn Sie ASP.NET nicht verwenden, ist dies ein guter Link zu einigen Artikeln von 4Guys und CodeProject

http://aspnet.4guysfromrolla.com/articles/081705-1.aspx http://aspnet.4guysfromrolla.com/articles/103002-1.aspx http://www.codeproject.com/kb/security/simpleencryption.aspx

Da es sich bei Ihrer Frage um Speichermethoden und Größe handelt, werde ich das ansprechen.

Speichertyp kann entweder binäre oder Textdarstellung sein (Base64 ist am häufigsten). Binär ist kleiner, aber ich finde es einfacher, mit Text zu arbeiten. Wenn Sie pro Benutzer Salzen (unterschiedliches Salz pro Passwort) ausführen, ist es einfacher, Salz+Hash als einzelne kombinierte Zeichenfolge zu speichern.

Die Größe ist Hash -Algorithmus abhängig. Der Ausgang von MD5 beträgt immer 16 Bytes, SHA1 ist immer 20 Bytes. SHA-256 & SHA-512 sind 32 bzw. 64 Bytes. Wenn Sie eine Textcodierung verwenden, benötigen Sie je nach Codierungsmethode etwas mehr Speicher. Ich neige dazu, Base64 zu verwenden, da der Speicher relativ billig ist. Base64 wird ungefähr 33% größeres Feld benötigen.

Wenn Sie pro Benutzer Salzen haben, benötigen Sie auch Platz für den Hash. Wenn Sie alles zusammenstellen, werden 64 -Bit -Salz + SHA1 -Hash (160 -Bit) Base64 Coded 40 Zeichen erforderlich, also speichere ich es als Char (40).

Wenn Sie es richtig machen möchten, sollten Sie keinen einzigen Hash, sondern eine wichtige Absivierungsfunktion wie RBKDF2 verwenden. SHA1- und MD5 -Hashes sind wahnsinnig schnell. Sogar eine einzelne Thread -Anwendung kann etwa 30.000 bis 50.000 Passwörter pro Sekunde haben, die bis zu 200K -Passwörter pro Sekunde auf Quad Core -Maschine sind. GPUs kann 100x bis 1000x so viele Passwörter pro Sekunde hasht. Mit Geschwindigkeiten wie der Angriffskraft wird zu einer akzeptablen Intrusion -Methode. Mit RBKDF2 können Sie die Anzahl der Iterationen angeben, um die "langsame" Hashing zu beachten. Der Punkt ist nicht, das System auf die Knie zu bringen, aber eine Reihe von Iterationen auszuwählen, damit Sie die Obergrenze für den Hash -Durchsatz begrenzen (z. B. 500 Hashes pro Sekunde). Eine zukünftige Beweismethode wäre, die Anzahl der Iterationen in das Kennwortfeld (Iterationen + Salz + Hash) aufzunehmen. Dies würde es ermöglichen, dass zunehmende Iterationen in Zukunft mit leistungsfähigeren Prozessoren Schritt halten. Noch flexibler zu sein, verwenden Sie Varchar, um in Zukunft potenziell größere/alternative Hashes zu ermöglichen.

Die .NET -Implementierung ist RFC2892DeriveByteshttp://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top