Frage Bevorzugte Methode zum Speichern von Passwörtern in der Datenbank


Was ist Ihre bevorzugte Methode / Datentyp zum Speichern von Passwö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 sie dann als binär in der Datenbank zu speichern (16). Ist dies die bevorzugte Methode oder sollte ich einen anderen Datentyp verwenden oder mehr Speicherplatz als 16 zuweisen?


76
2018-03-05 17:10


Ursprung


Antworten:


Ich speichere das gesalzene Hash-Äquivalent des Passworts in der Datenbank und nie das Passwort selbst, dann vergleiche immer den Hash mit dem generierten Wert dessen, was der Benutzer eingegeben hat.

Es ist zu gefährlich, die wörtlichen Passwortdaten irgendwo 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.


80
2018-03-05 17:12



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


47
2018-03-05 17:16



Ich mache dasselbe, was Sie beschrieben haben, außer dass es als String gespeichert ist. I Base64 verschlüsselt den verschlüsselten Binärwert. Die Menge des zu reservierenden Speicherplatzes hängt vom Verschlüsselungsalgorithmus / Verschlüsselungsgrad ab.

Ich denke, du machst es richtig (da du ein Salz).


15
2018-03-05 17:15



Da das Ergebnis einer Hash-Funktion eine Reihe von Bytes im Bereich von 0 bis 255 (oder -128 bis 127, abhängig von der Vorzeichenhaftigkeit Ihres 8-Bit-Datentyps) ist, ist es am sinnvollsten, sie als ein rohes Binärfeld zu speichern , da es die kompakteste Darstellung ist und keine zusätzlichen Codierungs- und Decodierungsschritte benötigt.

Einige Datenbanken oder Treiber haben keine große Unterstützung für binäre Datentypen, oder manchmal sind Entwickler einfach nicht vertraut genug, um sich wohl zu fühlen. In diesem Fall ist es akzeptabel, eine Binär-zu-Text-Codierung wie Base-64 oder Base-85 zu verwenden und den resultierenden Text in einem Zeichenfeld zu speichern.

Die Größe des Feldes wird durch die von Ihnen verwendete Hash-Funktion bestimmt. MD5 gibt immer 16 Byte aus, SHA-1 immer 20 Byte. Sobald Sie eine Hash-Funktion ausgewählt haben, sind Sie normalerweise damit beschäftigt, da das Ändern alle vorhandenen Kennwörter zurücksetzen muss. Wenn Sie also ein Feld mit variabler Größe verwenden, kaufen Sie nichts.


In Bezug auf den "besten" Weg, das Hashing durchzuführen, habe ich versucht, viele Antworten auf andere SO-Fragen zu diesem Thema zu geben:


8
2018-03-05 17:22



  1. Speichere den Hash des gesalzenen Passwortes, zB bcrypt (nounce + pwd). Sie bevorzugen möglicherweise bcrypt über SHA1 oder MD5, da es auf CPU-intensive gestimmt werden kann, wodurch ein Brute-Force-Angriff viel länger dauert.
  2. fügen Sie nach einigen Anmeldefehlern ein Captcha in das Login-Formular ein (um Brute-Force-Attacken zu vermeiden)
  3. Wenn Ihre Anwendung den Link "Passwort vergessen" enthält, stellen Sie sicher, dass das neue Passwort nicht per E-Mail gesendet wird. Stattdessen sollte ein Link zu einer (gesicherten) Seite gesendet werden, damit der Benutzer ein neues Passwort definieren kann (möglicherweise erst nach Bestätigung) von einigen persönlichen Informationen, wie zum Beispiel das Geburtsdatum des Benutzers). Wenn Ihre Anwendung es dem Benutzer ermöglicht, ein neues Kennwort zu definieren, stellen Sie sicher, dass der Benutzer das aktuelle Kennwort bestätigen muss.
  4. und natürlich, sichern Sie das Login-Formular (in der Regel mit HTTPS) und die Server selbst

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

  1. => Offline-Wörterbuchangriffe
  2. => Live-Wörterbuchangriffe
  3. => Denial-of-Service-Angriffe
  4. => alle Arten von Angriffen!

8
2018-03-05 17:51



Ich verwende den Sha-Hash des Benutzernamens, eine Guid in der Web-Konfiguration und das Passwort, das als varchar (40) gespeichert ist. Wenn sie Brute Force / Dictionary wollen, müssen sie auch den Webserver für die GUID hacken. Der Benutzername unterbricht die Erstellung einer Rainbow-Tabelle in der gesamten Datenbank, wenn sie das Kennwort finden. Wenn ein Benutzer seinen Benutzernamen ändern möchte, setze ich einfach das Passwort zur gleichen Zeit zurück.

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

4
2018-03-05 23:05



Ein einfacher Hash des Passwortes oder gar (Salz + Passwort) ist im Allgemeinen nicht ausreichend.

sehen:

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

und

http://gom-jabbar.org/articles/2008/12/03/why-you-should-use-bcrpt-to-store-your-passwords

Beide empfehlen die bcrypt-Algorithmen. Kostenlose Implementierungen können online für die meisten gängigen Sprachen gefunden werden.


3
2018-03-05 18:05



Sie können mehrere Hashes in Ihrer Datenbank verwenden, es erfordert nur ein wenig zusätzlichen Aufwand. Es lohnt sich jedoch, wenn Sie der Meinung sind, dass es die geringste Chance gibt, in Zukunft weitere Formate zu unterstützen. Ich benutze oft Passworteinträge wie

{hashId} $ {salz} $ {hashed password}

wo "hashId" nur eine Nummer ist, die ich intern verwende, um das zu erkennen, z. B. verwende ich SHA1 mit einem spezifischen Hash-Muster; "Salz" ist ein Base64-codiertes Zufallssalz; und "hashed password" ist ein base64-codierter Hash. Wenn Sie Hashes migrieren müssen, können Sie Personen mit einem alten Passwortformat abfangen und sie dazu bringen, ihr Passwort bei der nächsten Anmeldung zu ändern.

Wie andere bereits erwähnt haben, sollten Sie vorsichtig mit Ihren Hashes sein, da es leicht ist, etwas zu tun, das nicht wirklich sicher ist, zB H (Salz, Passwort) ist viel schwächer als H (Passwort, Salz), aber Sie wollen es gleichzeitig den damit verbundenen Aufwand mit dem Wert des Seiteninhalts ausgleichen. Ich werde oft H (H (Passwort, Salz), Passwort) verwenden.

Schließlich sind die Kosten für die Verwendung von base64-codierten Kennwörtern bescheiden im Vergleich zu den Vorteilen, die sich aus der Verwendung verschiedener Tools ergeben, die Textdaten erwarten. Ja, sie sollten flexibler sein, aber sind Sie bereit, Ihrem Chef zu sagen, dass er sein Lieblingswerkzeug von Drittanbietern nicht verwenden kann, weil Sie ein paar Bytes pro Datensatz speichern möchten? :-)

Bearbeitet, um einen weiteren Kommentar hinzuzufügen: Wenn ich vorschlage, einen Algorithmus zu verwenden, der selbst eine 1/10 Sekunde Hashing jedes Passwortes brennt, wäre ich glücklich, wenn ich nur aus dem Büro meines Chefs ausgelacht würde. (Nicht so glücklich? Er würde etwas notieren, um bei meiner nächsten jährlichen Überprüfung zu diskutieren.) Diese Zeit zu verbrennen ist kein Problem, wenn Sie Dutzende oder sogar Hunderte von Benutzern haben. Wenn Sie 100k Nutzer drängen, haben Sie normalerweise mehrere Personen, die sich gleichzeitig anmelden. Du brauchst etwas, schnell und stark, nicht langsam und stark. Die "Aber was ist mit den Kreditkarteninformationen?" ist bestenfalls unaufrichtig, da gespeicherte Kreditkarteninformationen nicht in der Nähe Ihrer regulären Datenbank liegen sollten und ohnehin von der Anwendung verschlüsselt würden, nicht von einzelnen Benutzern.


3
2018-03-23 16:17



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

Es unterstützt viele Arten von Speicheroptionen, einschließlich; Einweg-Hash, Zwei-Wege-Verschlüsselung, MD5 + Salz. http://www.asp.net/learn/security Für mehr Information.

Wenn Sie nichts zu ausgefallenes brauchen, ist dies ideal für Websites.

Wenn Sie nicht mit ASP.Net arbeiten ist hier ein guter Link zu ein paar 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


2
2018-03-05 18:24