web-dev-qa-db-ger.com

Lohnt sich das Hashing von Passwörtern auf der Clientseite?

Wenn ich ein Anmeldesystem einrichten möchte, vergleiche ich immer das MD5 des angegebenen Kennworts mit seinem Wert in der Benutzertabelle auf der Serverseite.

Ein Freund von mir sagte mir jedoch, dass ein "klares" Passwort von einer Netzwerksoftware beschnüffelt werden könne.

Meine Frage ist also: Ist es eine gute Idee, das Passwort auf der Client-Seite zu hacken? Ist es besser, als es auf der Serverseite zu haschen?

117
Zakaria

Grundsätzlich hat dein Freund recht. Das einfache Hashing des Kennworts auf der Clientseite ist jedoch nur besser, als es als Klartext an den Server zu senden. Jemand, der auf Ihre Klartext-Passwörter lauschen kann, kann sicherlich auch auf gehashte Passwörter lauschen und diese erfassten Hashes selbst verwenden, um sich bei Ihrem Server zu authentifizieren.

Aus diesem Grund springen sicherere Authentifizierungsprotokolle normalerweise durch eine Reihe von Rahmen, um sicherzustellen, dass ein solcher Wiederholungsangriff in der Regel nicht funktioniert, indem der Client eine Reihe von zufälligen Bits auswählen kann, die zusammen mit dem Kennwort gehasht werden , und auch im Klartext an den Server übermittelt.

Auf dem Server:

  • erzeugen ein paar zufällige Bits
  • senden Sie diese Bits (im Klartext) an den Client

Auf dem Client:

  • generiere ein paar zufällige Bits
  • verketten Sie das Passwort, die Zufallsbits des Servers und die Client-Zufallsbits
  • generieren Hash der oben genannten
  • senden Sie zufällige Daten (im Klartext) und Hash an den Server

Da der Server sowohl seine eigenen zufälligen Informationen als auch die zufälligen Bits des Clients kennt (sie werden als Klartext ausgegeben), kann er im Wesentlichen dieselbe Transformation durchführen. Dieses Protokoll stellt sicher, dass niemand, der in dieser Konversation mithört, die Informationen später zur fälschlichen Authentifizierung anhand der aufgezeichneten Informationen verwenden kann (es sei denn, es wurde ein sehr schwacher Algorithmus verwendet ...), solange beide Parteien jedes Mal unterschiedliche "Rauschbits" erzeugen. Der Handschlag wird ausgeführt.

Bearbeiten All dies ist fehleranfällig und mühsam und etwas schwer zu korrigieren (lesen: sicher). Erwägen Sie nach Möglichkeit die Verwendung von Authentifizierungsprotokollimplementierungen, die bereits von sachkundigen Personen geschrieben wurden (im Gegensatz zu mir! Das Obige stammt nur aus der Erinnerung an ein Buch, das ich vor einiger Zeit gelesen habe.). Sie möchten dies normalerweise nicht selbst schreiben.

103
Dirk

Zuallererst verbessert dies NICHT die Sicherheit Ihrer Anwendung (vorausgesetzt, es handelt sich um eine Webanwendung).

Verwenden Sie SSL (Oder eigentlich TLS, was allgemein als SSL bezeichnet wird), es ist nicht wirklich teuer (Messen Sie die Zeit, die Sie verwenden, um Wege zu finden und mit dem Mindestlohn zu multiplizieren, und kaufen Sie ein Zertifikat gewinnt fast immer).

Das Warum dazu ist einfach. TLS löst ein Problem (bei Verwendung mit gekauften Zertifikaten, die nicht selbst signiert sind), das in der Kryptografie eine große Rolle spielt: Woher weiß ich, dass der Server, mit dem ich spreche, der Server ist, mit dem ich zu sprechen glaube? TLS-Zertifikate sind eine Art zu sagen: "Ich, die Zertifizierungsstelle, die von Ihrem Browser als vertrauenswürdig eingestuft wird, bescheinigt, dass die Website unter [url] über diesen öffentlichen Schlüssel verfügt, mit einem entsprechenden privaten Schlüssel, den nur der Server kennt (privater Schlüssel) Ich habe das gesamte Dokument mit meiner Unterschrift versehen.

Ohne TLS macht jede Verschlüsselung keinen Sinn, denn wenn ich in einem Coffeeshop neben Ihnen sitze, kann ich Ihren Laptop/Ihr Smartphone glauben lassen, ich bin der Server und MiTM (Man in The Middle) Sie. Mit TLS schreit Ihr Laptop/Smartphone "UNTRUSTED CONNECTION", weil ich kein von einer Zertifizierungsstelle signiertes Zertifikat habe, das Ihrer Site entspricht. (Verschlüsselung vs. Authentifizierung).

Haftungsausschluss: Benutzer klicken sich in der Regel durch die folgenden Warnungen: "Nicht vertrauenswürdige Verbindung? Was? Ich möchte nur meine Bilder von Kätzchen! Ausnahme hinzufügen Klicken Bestätigen Klicken YAY! Kätzchen! "

Wenn Sie jedoch wirklich kein Zertifikat kaufen möchten, müssen Sie trotzdem Implementieren Sie clientseitiges Javascript-Hashing (und verwenden Sie dazu die Standford-Bibliothek (SJCL) Implementieren Sie Crypto Yourself NIEMALS ).

Warum? Passwort wiederverwenden! Ich kann Ihren Sitzungscookie (der es mir ermöglicht, Ihrem Server vorzutäuschen, dass ich Sie bin) ohne HTTPS leicht stehlen (siehe firesheep). Wenn Sie jedoch ein Javascript zu Ihrer Anmeldeseite hinzufügen, das vor dem Senden Ihr Passwort verschlüsselt (verwenden Sie SHA256 oder besser SHA256, senden Sie ihnen einen von Ihnen generierten öffentlichen Schlüssel und verschlüsseln Sie dann das Passwort damit, können Sie kein Salt verwenden mit diesem) und sendet dann das gehashte/verschlüsselte Passwort an den Server. REHASH den Hash auf deinem Server mit einem Salt und vergleiche das mit dem, was in deiner Datenbank gespeichert ist (speichere das Passwort wie folgt:

(SHA256(SHA256(password)+salt))

(Speichern Sie das Salz auch als Klartext in der Datenbank). Und senden Sie Ihr Passwort wie folgt:

RSA_With_Public_Key(SHA256(password))

und überprüfe dein Passwort wie folgt:

if SHA256(RSA_With_Private_Key(SHA256(sent_password))+salt_for_username) == stored_pass: login = ok

Weil, WENN jemand an Ihrem Client schnüffelt, er sich als Ihr Client anmelden kann (Session-Hijacking), aber er wird [~ # ~) ] never [~ # ~] sehe das Klartext-Passwort (es sei denn, sie ändern dein Javascript, aber ein Starbucks-Hacker wird wahrscheinlich nicht wissen, wie es geht/daran interessiert sein.) Damit erhalten sie Zugriff auf deine Web-App, aber nicht auf ihre E-Mail/Facebook/etc. (für die Ihre Benutzer wahrscheinlich dasselbe Passwort verwenden werden). (Die E-Mail-Adresse ist entweder ihr Benutzername oder sie finden sie in ihrem Profil/ihren Einstellungen auf Ihrer Webanwendung).

Sie werden sich wahrscheinlich keine Sorgen darüber machen - Dirk erwähnt, dass ein böswilliger Benutzer in einem Netzwerk sein und sehen kann, dass der Hash gesendet wird, und dass er denselben Hash auch selbst senden kann, selbst wenn Sie die Passwörter hacken.

Es ist leicht besser, da es den böswilligen Benutzer daran hindert, das Passwort zu kennen, aber da er sich trotzdem einloggen kann (oder möglicherweise das ursprüngliche Passwort wiederherstellen kann ) , das ist nicht so hilfreich.

Im Allgemeinen sollten Sie einen sicheren SSL-Server verwenden, wenn Sie sich um die Sicherheit der Passwörter und Daten Ihres Benutzers sorgen (und das sollten Sie auch tun!). Wenn Sie dies aus irgendeinem Grund nicht befürchten, kümmern Sie sich genauso gut nicht um das Hashing. es ist nur Sicherheit durch Dunkelheit .


Edit Aug 2014: Google drängt immer stärker auf Websites überall auf HTTPS umstellen , weil die Absicherung der Kommunikation selbst erfolgt der einzige Weg, um Netzwerk-Sniffing-Angriffe zu verhindern. Versuche, die übertragenen Daten zu verschleiern, werden einen dedizierten Angreifer nur behindern, nicht stoppen und können Entwicklern ein gefährliches falsches Sicherheitsgefühl vermitteln.

21
dimo414

Eigentlich bin ich nicht der Meinung, dass clientseitiges Hashing in diesem Fall sicherer ist. Ich denke, es ist weniger sicher.

Der gesamte Punkt des Speicherns eines Hash des Passworts in Ihrer Datenbank im Gegensatz zum realen Passwort (oder sogar einem verschlüsselten Passwort) besteht darin, dass es mathematisch unmöglich ist, das ursprüngliche Passwort aus einem Hash zu erhalten (obwohl es theoretisch möglich ist, eine Kollision zu erhalten Hash-Eingabe, deren Schwierigkeit von der Sicherheitsstärke des Hash-Algorithmus abhängt). Der mögliche Angriffsvektor besteht darin, dass ein potenzieller Angreifer, der Ihre Kennwortspeicherdatenbank in irgendeiner Weise kompromittiert hat, die ursprünglichen Kennwörter Ihrer Benutzer immer noch nicht erhalten kann.

Wenn Ihr Authentifizierungsmechanismus einen Hash des Kennworts sendet, muss der Angreifer in diesem Sicherheitsverletzungsszenario das tatsächliche Kennwort nicht kennen. Er sendet lediglich den Hash, den er besitzt, und hat Zugriff auf das Konto eines bestimmten Benutzers. und damit Ihr gesamtes System. Dies macht das Speichern eines Hash-Passworts überflüssig!

Die wirklich sichere Möglichkeit besteht darin, dem Client einen einmaligen öffentlichen Schlüssel zum Verschlüsseln des Kennworts zu senden. Anschließend entschlüsseln Sie das Kennwort und hacken es auf der Serverseite erneut.

Übrigens wird diese Art von Frage wahrscheinlich mehr Expertenantworten auf Security StackExchange erhalten.

9
Kidburla

Es kommt darauf an, dass Sie clientseitiges Hashing verwenden können, serverseitiges Salting jedoch nicht möglich ist.

werfen Sie einen Blick auf den Link Passwortverschlüsselung auf der Clientseite

3
SmAxlL

Beachten Sie, dass das Schützen von Passwörtern gegen Dritte nicht alles ist, was Sie brauchen.

Sobald es um Datenschutz geht (und wann immer nicht?) Sie möchten das Passwort nicht wissen. Sie können nicht missbrauchen oder auslaufen lassen, was Sie nicht haben, sodass sowohl Sie als auch Ihre Kunden besser schlafen können, wenn Sie nie ihre Klartext-Passwörter sehen.

Daher ist es sinnvoll, clientseitig zu haschen/verschlüsseln.

2
Raphael

Kürzlich gaben GitHub und Twitter bekannt, dass Passwörter in internen Logs gespeichert wurden. Ich habe dies versehentlich in Fehlerberichten und anderen Protokollen festgestellt, die ihren Weg in Splunk usw. fanden. Für Twitter könnte es eine große Sache sein, wenn Trumps Passwort im Protokoll enthalten ist, für andere Sites möglicherweise nicht so Eine große Sache, da die Administratoren nicht viel damit anfangen konnten. Unabhängig davon, ob wir Administratoren sind oder nicht, sehen wir gerne die Passwörter.

Die Frage ist also wirklich, ob das Hashing aus Sicherheitsgründen clientseitig erfolgen sollte, aber wie können wir das Passwort schützen, bevor es letztendlich gehasht und von der Serverseite verglichen wird, damit es nicht irgendwie protokolliert wird.

Die Verschlüsselung ist keine schlechte Idee, da die Entwickler zumindest einige Probleme lösen müssen. Wenn Sie feststellen, dass Passwörter in Protokolle eingedrungen sind, können Sie einfach den Verschlüsselungsschlüssel ändern, das Original zerstören und die Daten werden unbrauchbar. Besser noch die Schlüssel nachts drehen und es könnte die Fenster stark verkleinern.

Sie können auch einen Hash in Ihrem Benutzerdatensatz verwenden. Die durchgesickerten Passwörter wären verschlüsselte Klartext-Passwörter. Der Server würde eine gehashte Version des Hashes speichern. Sicher, der Hash wird zum Passwort, aber wenn Sie kein fotografisches Gedächtnis haben, werden Sie sich nicht an ein 60-Zeichen-Passwort erinnern. Salt mit dem Benutzernamen. Wenn Sie während des Anmeldevorgangs etwas über den Benutzer herausfinden können (ohne dass der Benutzerdatensatz vorhanden ist), können Sie damit auch einen robusteren Hash erstellen, der nicht zwischen Websites geteilt werden kann. Kein Mann in der Mitte wäre in der Lage, den erfassten Hash zwischen den Standorten auszuschneiden und einzufügen.

Kombinieren Sie mit einem Cookie, das nicht an den Server zurückgesendet wird und Sie möglicherweise auf etwas stoßen. Senden Sie auf erste Anfrage ein Cookie mit einem Schlüssel an den Client. Stellen Sie dann sicher, dass das Cookie nicht zum Anmeldedienst zurückkehrt, da die Wahrscheinlichkeit gering ist, dass es angemeldet wird. Speichern Sie den Schlüssel in einem Sitzungsspeicher und löschen Sie ihn direkt nach dem Anmelden oder nach dem Ablauf der Sitzung. Dies erfordert den Status für Sie, JWT-Mitarbeiter, aber verwenden Sie möglicherweise nur einen NOSQL-Dienst.

Auf diese Weise stößt ein Administrator auf eines dieser gehashten und verschlüsselten Passwörter in Splunk oder einem Tool zur Fehlerberichterstattung. Es sollte für sie nutzlos sein, da sie den Chiffrierschlüssel nicht mehr finden können und selbst dann einen Hash erzwingen müssen. Außerdem hat der Endbenutzer keinen Klartext gesendet, sodass es jedem Mann in der Mitte zumindest schwerer fällt und Sie nicht einfach zu einer anderen Site springen und sich anmelden können.

1
Eric Twilegar

Ich habe in letzter Zeit viel daran gearbeitet, IRL, es gibt zwei Probleme mit clientseitigem Hash/ symmetrischer Verschlüsselung, die wirklich die Idee zunichte machen: 1 Sie müssen das Salz irgendwie auf den Server zurückbringen ... und um es clientseitig zu verschlüsseln, benötigen Sie ein Passwort ... das den Zweck zunichte macht. 2. Sie legen Ihre Hashing-Implementierung offen (kein RIESIGES Geschäft, da die meisten Sites einen von 3 oder 4 Hashing-Algen verwenden), was den Angriff einfacher macht (da Sie nur einen anstelle von n versuchen müssen).

Was ich letztendlich unternommen habe, war asymmetrische Verschlüsselung auf dem Client mit OpenPGP.js oder ähnlichem ... Dies setzt voraus, dass ein importierter oder clientseitig generierter Schlüssel auf dem Client und dem Server seinen öffentlichen Schlüssel sendet. Es kann nur der öffentliche Schlüssel des Clients an den Server zurückgesendet werden. Dies schützt vor MIM-Angriffen und ist so sicher wie das Gerät (derzeit speichere ich den privaten Schlüssel des Clients standardmäßig in localStore, es ist eine Demo).

Der Hauptvorteil davon ist, dass ich Benutzerdaten niemals unverschlüsselt auf meinem Server/Datenspeicher speichern/speichern muss (und der private Schlüssel meines Servers physisch getrennt ist).

Die Basis dafür war, Menschen eine Möglichkeit zu bieten, sicher zu kommunizieren, wo HTTPS eingeschränkt war (z. B. Iran/Nordkorea atc ​​...), und auch nur ein unterhaltsames Experiment.

Ich bin weit davon entfernt, darüber nachzudenken, http://www.mailvelope.com/ verwendet dies

1
ScottGal

Wenn jemand die Daten in und aus Ihrer Verbindung sehen kann, werden Sie durch die Authentifizierung nicht gerettet. Stattdessen würde ich folgendes für super geheime Sachen tun.

Passwörter, die auf der Client-Seite vorgespeichert wurden, bevor sie an den Server gesendet wurden. (Server speichert einen weiteren Hash und Salt-Wert des vom Browser gesendeten Hash).

Ein Middle-Man-Angriff könnte es ihnen ermöglichen, denselben Hash-Wert für die Anmeldung wie sie zu senden, das Kennwort des Benutzers wäre jedoch nicht bekannt. Dies würde sie daran hindern, andere Dienste mit denselben Anmeldeinformationen zu versuchen, sich an anderer Stelle anzumelden.

Benutzerdaten werden auch auf der Browserseite verschlüsselt.

Ah, also würde ein Middle-Man-Angriff die verschlüsselten Daten erhalten, aber nicht in der Lage sein, sie zu entschlüsseln, ohne das eigentliche Passwort, das für die Anmeldung verwendet wird. (Benutzerpasswort, das beim Anmelden im DOM des Browsers gespeichert wurde). Der echte Benutzer würde also den entschlüsselten Inhalt sehen, der mittlere jedoch nicht. Dies bedeutet auch, dass keine NSA oder andere Agentur Sie/Firma/Hosting-Anbieter auffordern kann, diese Daten zu entschlüsseln, da dies auch für sie unmöglich ist.

Einige kleine Beispiele für diese beiden Methoden finden Sie in meinem Blog http://glynrob.com/javascript/client-side-hashing-and-encryption/

1
GlynRob

Bedenken Sie:-

Der Client sendet eine Anfrage an den Server "Ich habe ein zu überprüfendes Passwort".

Der Server sendet dem Client eine einmalige Zufallszeichenfolge. R $

Der Client bettet das Kennwort des Benutzers in diese Zeichenfolge ein (basierend auf beliebigen (variablen) Regeln, die Sie anwenden möchten).

Der Client sendet die Zeichenfolge an den Server. Wenn das Kennwort in Ordnung ist, meldet der Server den Benutzer an.

Sollte der Server eine weitere Anmeldeanforderung mit R $ erhalten, wird der Benutzer abgemeldet und das Konto wird bis zur Untersuchung gesperrt.

Offensichtlich würden alle anderen (normalen) Sicherheitsvorkehrungen getroffen.

0
cneeds