Beste Möglichkeit, Passwort in Datenbank zu speichern [geschlossen]

475

Ich arbeite an einem Projekt, das eine Authentifizierung haben muss (Benutzername und Passwort).

Es stellt auch eine Verbindung zu einer Datenbank her, sodass ich dachte, ich würde den Benutzernamen und das Passwort dort speichern. Es scheint jedoch keine so gute Idee zu sein, Passwörter als nur ein Textfeld in einer Tabelle in der Datenbank zu haben.

Ich verwende C # und verbinde mich mit einem 2008 Express-Server. Kann jemand (mit so vielen Beispielen wie möglich) vorschlagen, wie diese Art von Daten am besten gespeichert werden kann?

PS Ich bin offen für die Idee, dass diese Informationen nicht in der Datenbank gespeichert werden, wenn ein guter Grund angegeben werden kann

Crash893
quelle
1
Was auch immer Sie tun, wenn Sie mit Verschlüsselung arbeiten, speichern Sie den Schlüssel nicht im Code wie in einem zuvor erwähnten Poster. Das ist nur schlechte Übung.
Woody
12
"Wie mache ich Passwörter richtig?" ist eine wichtige Frage. Es ist ein schwieriges Problem und Fehler haben schwerwiegende Folgen (erinnern Sie sich daran, was mit Tesco und LinkedIn passiert ist). Ich denke, diese Frage sollte unter programmers.stackexchange.com
Colonel Panic
2
Es ist besser, sich an Standards zu halten - siehe en.wikipedia.org/wiki/PBKDF2. Sie müssen nur eine Implementierung in Ihrer Sprache finden
Boris Treukhov
5
Diese Frage wird ausführlich im Sicherheitsforum beantwortet: security.stackexchange.com/questions/211/…
gioele

Antworten:

405

Sie haben Recht, dass das Speichern des Passworts in einem Klartextfeld eine schreckliche Idee ist. In Bezug auf den Standort ist es jedoch in den meisten Fällen richtig (und ich kann mir ehrlich gesagt keine Gegenbeispiele vorstellen), die Darstellung eines Kennworts in der Datenbank zu speichern . Durch die Darstellung meine ich , dass Sie die Passwort - Hash wollen mit einem Salz (die für jeden Benutzer anders sein sollen) und einen sicheren 1-Weg - Algorithmus und zu speichern , dass , wirft das ursprüngliche Passwort weg. Wenn Sie dann ein Kennwort überprüfen möchten, hashen Sie den Wert (unter Verwendung des gleichen Hashing-Algorithmus und Salt) und vergleichen ihn mit dem Hash-Wert in der Datenbank.

Also, während es eine gute Sache ist, dass Sie darüber nachdenken und es eine gute Frage ist, ist dies tatsächlich ein Duplikat dieser Fragen (zumindest):

Um das Salting-Bit etwas näher zu erläutern, besteht die Gefahr, dass ein Eindringling, der Ihre Datenbank in den Griff bekommt, weiterhin sogenannte Regenbogentabellen verwenden kann , um das zu "entschlüsseln" Passwort (zumindest diejenigen, die in der Regenbogentabelle angezeigt werden). Um dies zu umgehen , fügen Entwickler Passwörtern ein Salz hinzu , das bei richtiger Ausführung Regenbogenangriffe einfach unmöglich macht. Beachten Sie, dass ein häufiges Missverständnis darin besteht, allen Passwörtern einfach dieselbe eindeutige und lange Zeichenfolge hinzuzufügen. Obwohl dies nicht schrecklich ist , ist es am besten, jedem Passwort eindeutige Salze hinzuzufügen. Lesen Sie dies für mehr.

Paolo Bergantino
quelle
40
Ich meinte, das Passwort in der Datenbank zu speichern, anstatt es an anderer Stelle zu speichern. Wenn ich diesen Satz aus dem Zusammenhang nehme, scheint es, als würde ich das Speichern einfacher Passwörter unterstützen. Wenn Sie den Rest lesen, tue ich das offensichtlich nicht.
Paolo Bergantino
14
Das habe ich nicht nur gesagt, ich habe ihn auch auf eine Vielzahl von Posts verwiesen, in denen es um Salze und dergleichen geht ...
Paolo Bergantino
1
@Paolo Bergantino: Bist du sicher, dass dein Beitrag keinen Tippfehler enthält? Es heißt: "In den meisten Fällen (und ich kann mir ehrlich gesagt keine Gegenbeispiele vorstellen) ist es richtig, das Passwort in der Datenbank zu speichern." ??? Es scheint Ihren Kommentaren zu widersprechen
Mitch Wheat
3
Was Paolo sagte, widerspricht sich direkt. Ein gesalzener Hash eines Passworts ist kein Passwort. Durch das Speichern eines gesalzenen Hash des Kennworts in der Datenbank wird das Kennwort nicht in der Datenbank gespeichert. Der Hauptteil der Antwort ist vollkommen angemessen, aber der erste Satz ist äußerst irreführend.
Robert Rossney
40
@ Robert: Das kommt einem kleinen Semantikspiel gefährlich nahe, aber ich werde es trotzdem beheben ...
Paolo Bergantino
54

Hintergrund Sie müssen nie ... wirklich ... das Passwort des Benutzers kennen. Sie möchten nur überprüfen, ob ein eingehender Benutzer das Kennwort für ein Konto kennt.

Hash It: Speichern von Benutzerkennwörtern (Einwegverschlüsselung) über eine starke Hash-Funktion. Eine Suche nach "c # encrypt passwords" liefert eine Vielzahl von Beispielen.

Im Online-SHA1-Hash-Ersteller finden Sie eine Vorstellung davon, was eine Hash-Funktion erzeugt (verwenden Sie SHA1 jedoch nicht als Hash-Funktion, sondern verwenden Sie etwas Stärkeres wie SHA256).

Ein Hash-Passwort bedeutet nun, dass Sie (und Datenbankdiebe) diesen Hash nicht mehr in das ursprüngliche Passwort umkehren sollten.

Wie man es benutzt: Aber wie verwende ich dieses in der Datenbank gespeicherte Passwort?

Wenn sich der Benutzer anmeldet, erhalten Sie den Benutzernamen und das Kennwort (im Originaltext). Sie verwenden nur denselben Hash-Code, um das eingegebene Kennwort zu hashen und die gespeicherte Version abzurufen.

Vergleichen Sie also die beiden Hash-Passwörter (Datenbank-Hash für Benutzername und das eingegebene & Hash-Passwort). Sie können feststellen, ob "was sie eingegeben haben" mit "übereinstimmt, was der ursprüngliche Benutzer für sein Passwort eingegeben hat", indem Sie ihre Hashes vergleichen.

Extra Gutschrift:

Frage: Wenn ich Ihre Datenbank hätte, könnte ich dann nicht einfach einen Cracker wie John the Ripper nehmen und Hashes erstellen, bis ich Übereinstimmungen mit Ihren gespeicherten Hash-Passwörtern finde? (da Benutzer sowieso kurze Wörter aus dem Wörterbuch auswählen ... sollte es einfach sein)

Antwort: Ja ... ja, das können sie.

Sie sollten also Ihre Passwörter "salzen". Siehe den Wikipedia-Artikel über Salz

Siehe "Wie man Daten mit Salz hasht" C # -Beispiel

Joej
quelle
14
Netter Beitrag, bis auf eines: md5 und sha1 sind beide kaputt. Sie sollten wahrscheinlich einen stärkeren Algorithmus verwenden, z. B. die SHA2-Familie.
Paolo Bergantino
3
Danke Paolo - du hast recht. Da die Verwendung von SHA2 so einfach ist wie die Verwendung von MD5 und SHA1, verwenden Sie bitte den stärkeren Hash-Algorithmus.
Joej
5
SHA-1 wurde nicht gebrochen. Aber um Bruce Schneier zu paraphieren: Gehen Sie, rennen Sie nicht, zu SHA-2.
Ian Boyd
2
"Also sollten Sie Ihre Passwörter 'salzen'" ... Aber das Salz wird normalerweise zusammen mit dem Passwort in der Datenbank gespeichert. Wie hilft das? Der Angreifer muss lediglich das Salz zu den Wörterbuch-Angriffsphrasen hinzufügen, gegen die er testet. Wie ist das sicherer, als dass es keine doppelten Passwörter preisgibt?
Trusktr
4
@joej "Sie müssen nie ... wirklich ... das Passwort des Benutzers kennen" - das ist eine sehr kurzsichtige Annahme. Es gibt viele Arten von Anwendungen, bei denen es wirklich notwendig ist, ein Kennwort so zu speichern, dass es abgerufen werden kann. Zum Beispiel eine Anwendung, die sich häufig bei einem anderen System mit gespeicherten Anmeldeinformationen anmelden muss, die von einem Benutzer bereitgestellt und aktualisiert werden.
Francisco Zarabozo
29

Als schlüsselgehärteter gesalzener Hash unter Verwendung eines sicheren Algorithmus wie sha-512.

Nilamo
quelle
6
Meiner Meinung nach sollten Sie immer langsame Algorithmen (wie zum Beispiel Blowfish) verwenden, um Passwörter zu speichern. Diese Beschreibung ist eine viel bessere Antwort: security.stackexchange.com/questions/211/… . Setzen Sie es einfach hier ein, denn diese Seite erscheint immer noch hoch in den Suchergebnissen.
Dynom
2
Das Befolgen dieser Ratschläge zur Speicherung von Passwörtern wäre absolut falsch.
mlissner
27

Die beste Sicherheitspraxis besteht darin, das Kennwort überhaupt nicht (nicht einmal verschlüsselt) zu speichern, sondern den gesalzenen Hash (mit einem eindeutigen Salt pro Kennwort) des verschlüsselten Kennworts zu speichern.

Auf diese Weise ist es (praktisch) unmöglich, ein Klartext-Passwort abzurufen.

Mitch Wheat
quelle
11
Wayne, indem er vor dem Berechnen des Hashs salzt, wird der Regenbogentisch effektiv besiegt, vorausgesetzt, das Salz hat eine ausreichende Größe.
Mike Rosenblum
11
@ Wayne Hartman: Nicht so. Wenn der Salzwert verfügbar ist, müssen Sie eine neue Regenbogentabelle für diesen bestimmten Salzwert erstellen. Der Punkt einer Regenbogentabelle besteht darin, Hash-Werte im Voraus berechnen zu lassen. Und niemand wird einen Regenbogentisch für sein spezielles Salz haben.
Ian Boyd
10

Ich würde dringend empfehlen, die Artikel Genug mit den Regenbogentabellen zu lesen : Was Sie über sichere Kennwortschemata wissen müssen [toter Link, Kopie im Internetarchiv ] und wie Sie ein Kennwort sicher speichern .

Viele Programmierer, auch ich, glauben, Sicherheit und Hashing zu verstehen. Leider tun es die meisten von uns einfach nicht.

Zebrabox
quelle
1
@Johan Sieht aus wie der Link jetzt gebrochen ist, was eine Schande ist. Hier ist eine Alternative codahale.com/how-to-safely-store-a-password
Zebrabox
6

Ich bin möglicherweise etwas vom Thema abweichend, da Sie die Notwendigkeit eines Benutzernamens und eines Passworts erwähnt haben und mein Verständnis des Problems zwar nicht das beste ist, aber ist OpenID eine Überlegung wert?

Wenn Sie OpenID verwenden, werden am Ende überhaupt keine Anmeldeinformationen gespeichert, wenn ich die Technologie richtig verstehe und Benutzer bereits vorhandene Anmeldeinformationen verwenden können, ohne dass eine neue Identität erstellt werden muss, die für Ihre Anwendung spezifisch ist.

Es ist jedoch möglicherweise nicht geeignet, wenn die betreffende Anwendung nur für den internen Gebrauch bestimmt ist

RPX bietet eine schöne einfache Möglichkeit, die OpenID-Unterstützung in eine Anwendung zu integrieren.

Crippledsmurf
quelle
Ich bin damit einverstanden, dass openID rockt, aber für diese Anwendung handelt es sich um eine interne Datenbank für ein Unternehmen, bei dem ich bezweifle, dass sich eine alte Person anmelden soll. Außerdem ist kein Webzugriff erforderlich, damit diese App ordnungsgemäß funktioniert. Ich würde es hassen, sie zu benötigen.
Crash893
3

In Ihrem Szenario können Sie einen Blick auf die asp.net-Mitgliedschaft werfen. Es wird empfohlen, das Kennwort des Benutzers als Hash-Zeichenfolge in der Datenbank zu speichern. Sie können den Benutzer authentifizieren, indem Sie das eingehende Hash-Kennwort mit dem in der Datenbank gespeicherten Kennwort vergleichen.

Alles wurde für diesen Zweck erstellt. Schauen Sie sich die asp.net-Mitgliedschaft an

Ray Lu
quelle
1

Ich würde MD5 / SHA1 das Passwort, wenn Sie nicht in der Lage sein müssen, den Hash umzukehren. Wenn sich Benutzer anmelden, können Sie das angegebene Kennwort einfach verschlüsseln und mit dem Hash vergleichen. Hash-Kollisionen sind in diesem Fall nahezu unmöglich, es sei denn, jemand erhält Zugriff auf die Datenbank und sieht einen Hash, für den er bereits eine Kollision hat.

waiwai933
quelle
2
Ich würde MD5 nicht zum Hashing verwenden - es ist im Grunde kaputt mscs.dal.ca/~selinger/md5collision
zebrabox
3
Eigentlich ist es nicht so kaputt. Sie können denselben Hashwert für zwei verschiedene Dateien finden. Was sie nicht tun können, ist das MD5 umzukehren und ein funktionierendes Passwort zu erhalten.
waiwai933
2
Wäre das dann nicht auch kaputt? Sie geben einfach das andere Passwort ein, das denselben Hash generiert, und Sie sind dabei. Sie müssen das ursprüngliche Passwort nicht kennen. Die Möglichkeit, dies zu beheben, besteht darin, das Kennwort vor dem Hashing zu salzen.
Mjuarez
2
@mjuarez Wenn Sie dem Passwort ein Salt hinzufügen, bevor Sie MD5 verwenden, spielt die Kollision keine Rolle, da Sie das andere Passwort nicht verwenden können
WiiMaxx