Ich habe festgestellt, dass die meisten Websites die Kennwörter als Klartext über HTTPS an den Server senden. Gibt es einen Vorteil, wenn ich stattdessen den Hash des Passworts an den Server gesendet habe? Wäre es sicherer?
Ich habe festgestellt, dass die meisten Websites die Kennwörter als Klartext über HTTPS an den Server senden. Gibt es einen Vorteil, wenn ich stattdessen den Hash des Passworts an den Server gesendet habe? Wäre es sicherer?
Antworten:
Dies ist eine alte Frage, aber ich hatte das Bedürfnis, meine Meinung zu dieser wichtigen Angelegenheit zu äußern. Hier gibt es so viele Fehlinformationen
Das OP hat nie erwähnt, dass das Passwort eindeutig über HTTP gesendet wird - nur über HTTPS. Viele scheinen jedoch aus irgendeinem Grund auf die Frage zu antworten, ob ein Passwort über HTTP gesendet werden soll. Das gesagt:
Ich glaube, Passwörter sollten niemals im Klartext aufbewahrt (geschweige denn übertragen) werden. Das heißt, nicht auf der Festplatte oder sogar im Speicher.
Die Leute, die hier antworten, scheinen zu denken, dass HTTPS eine Silberkugel ist, was es nicht ist. Es hilft jedoch sicherlich sehr und sollte in jeder authentifizierten Sitzung verwendet werden.
Es ist wirklich nicht nötig zu wissen, was ein ursprüngliches Passwort ist. Alles, was erforderlich ist, ist eine zuverlässige Möglichkeit, einen Authentifizierungs- "Schlüssel" basierend auf dem vom Benutzer ausgewählten Originaltext zu generieren (und zuverlässig neu zu generieren). In einer idealen Welt sollte dieser Text sofort einen "Schlüssel" erzeugen, indem er mit irreversiblem Salz gehasht wird. Dieses Salt sollte für den generierten Benutzerausweis eindeutig sein. Dieser "Schlüssel" wird von Ihren Systemen als Kennwort verwendet. Auf diese Weise sind diese Anmeldeinformationen nur für Ihre eigene Organisation nützlich, wenn Ihre Systeme in Zukunft jemals kompromittiert werden, und nirgendwo sonst, wo der Benutzer faul war und dasselbe Kennwort verwendet hat.
Wir haben also einen Schlüssel. Jetzt müssen wir alle Spuren des Passworts auf dem Client-Gerät bereinigen.
Als nächstes müssen wir diesen Schlüssel für Ihre Systeme erhalten. Sie sollten niemals einen Schlüssel oder ein Passwort "im Klartext" übermitteln. Nicht einmal über HTTPS. HTTPS ist nicht undurchdringlich. Tatsächlich können viele Organisationen zu vertrauenswürdigen MITM werden - nicht aus Angriffssicht, sondern um Inspektionen des Datenverkehrs durchzuführen, um ihre eigenen Sicherheitsrichtlinien zu implementieren. Dies schwächt HTTPS und ist nicht die einzige Möglichkeit (z. B. Weiterleitungen zu HTTP-MITM-Angriffen). Gehen Sie niemals davon aus, dass es sicher ist.
Um dies zu umgehen, haben wir den Schlüssel mit einer einmaligen Nonce gehasht. Diese Nonce ist für jede Übermittlung eines Schlüssels an Ihre Systeme eindeutig - auch für denselben Berechtigungsnachweis während derselben Sitzung, wenn Sie ihn mehrmals senden müssen. Sie können diese Nonce umkehren, sobald sie in Ihren eigenen Systemen eingetroffen ist, um den Authentifizierungsschlüssel wiederherzustellen und die Anforderung zu authentifizieren.
An dieser Stelle würde ich es ein letztes Mal irreversibel hashen, bevor es dauerhaft in Ihren eigenen Systemen gespeichert wird. Auf diese Weise können Sie das Salz des Berechtigungsnachweises für SSO-Zwecke und dergleichen mit Partnerorganisationen teilen, während Sie nachweisen können, dass Ihre eigene Organisation sich nicht als Benutzer ausgeben kann. Der beste Teil dieses Ansatzes ist, dass Sie niemals etwas teilen, das vom Benutzer ohne dessen Autorisierung generiert wurde.
Machen Sie mehr Nachforschungen, da mehr dahinter steckt, als ich selbst preisgegeben habe. Wenn Sie Ihren Benutzern jedoch echte Sicherheit bieten möchten, ist diese Methode meiner Meinung nach derzeit die vollständigste Antwort.
TL; DR:
Verwenden Sie HTTPS. Sichere Hash-Passwörter, irreversibel, mit einem eindeutigen Salt pro Passwort. Tun Sie dies auf dem Client - übertragen Sie nicht das tatsächliche Passwort. Das Übertragen des ursprünglichen Passworts des Benutzers an Ihre Server ist niemals "OK" oder "Gut". Bereinigen Sie alle Spuren des ursprünglichen Passworts. Verwenden Sie eine Nonce unabhängig von HTTP / HTTPS. Es ist auf vielen Ebenen viel sicherer. (Antwort an OP).
Da es über HTTPS geht, ist es definitiv in Ordnung, das Passwort ohne Hashing zu senden (über HTTPS ist es kein Klartext). Wenn Ihre Anwendung von HTTPS abhängig ist, um den Inhalt sicher zu halten, ist es außerdem nutzlos, das Kennwort vor dem Senden über HTTPS zu hashen (dh wenn ein Angreifer die Daten auf dem Kabel entschlüsseln kann, sind Sie trotzdem fertig).
Nein, tatsächlich wäre dies eine Sicherheitslücke. Wenn der Angreifer in der Lage ist, den Hash aus der Datenbank abzurufen, kann er ihn zur Authentifizierung verwenden, ohne ihn knacken zu müssen. Unter keinen Umständen sollte ein Benutzer oder Angreifer in der Lage sein, ein Hash-Passwort zu erhalten.
Der springende Punkt beim Hashing von Passwörtern ist das Hinzufügen einer zusätzlichen Sicherheitsebene. Wenn ein Angreifer in der Lage ist, den Hash und das Salt mithilfe von SQL Injection oder einer unsicheren Sicherung aus der Datenbank abzurufen, muss er den Klartext finden, indem er ihn brutal erzwingt. John The Ripper wird häufig verwendet, um gesalzene Passwort-Hashes zu brechen.
Die Nichtverwendung von https ist eine Verletzung der OWASP Top 10: A9-unzureichender Transportschichtschutz
BEARBEITEN:
Wenn Sie in Ihrer Implementierung einen sha256(client_salt+plain_text_password)
und dann einen weiteren Hash auf der Serverseite berechnen, sha256(server_salt+client_hash)
ist dies keine ernsthafte Sicherheitsanfälligkeit. Es ist jedoch weiterhin anfällig für das Abhören und Wiederholen der Anforderung. Somit ist dies immer noch eine eindeutige Verletzung von WASP A9. Dabei wird jedoch weiterhin ein Message Digest als Sicherheitsschicht verwendet.
Das nächste, was ich bei einem clientseitigen Ersatz für https gesehen habe, ist ein Diffie-Hellman beim Schlüsselaustausch in Javascript . Dies verhindert jedoch aktive MITM-Angriffe und ist somit bis zur technischen Verletzung eine Verletzung von OWASP A9. Die Autoren des Codes sind sich einig, dass dies kein vollständiger Ersatz für HTTPS ist, jedoch besser als nichts und besser als ein clientseitiges Hashing-System.
Das Senden eines Hashs über die Leitung macht den Zweck des Hashs völlig zunichte, da ein Angreifer den Hash einfach senden und das Passwort vergessen kann. Kurz gesagt, ein System, das die Verwendung eines Hashs im Klartext athentifiziert, ist weit offen und kann nur durch Netzwerk-Sniffing kompromittiert werden.
Das Passwort im Klartext zeigt nie (auch nicht bei Verwendung von HTTPS) den Client. Es sollte irreversibel gehasht werden, bevor der Client verlassen wird, da der Server das tatsächliche Kennwort nicht kennen muss.
Das Hashing und anschließende Senden löst Sicherheitsprobleme für faule Benutzer, die dasselbe Kennwort an mehreren Orten verwenden (ich weiß, dass ich es tue). Dies schützt Ihre Anwendung jedoch nicht als Hacker, der Zugriff auf die Datenbank erhalten hat (oder auf andere Weise in der Lage war, den Hash in die Hände zu bekommen), da der Hacker den Hash einfach übertragen und vom Server akzeptieren lassen konnte.
Um dieses Problem zu lösen, können Sie natürlich auch den vom Server empfangenen Hash hashen und ihn einen Tag lang aufrufen.
Mein Ansatz für das Problem in einer Socket-basierten Webanwendung, die ich erstelle, besteht darin, dass der Server bei Verbindung mit dem Client ein Salt generiert (zufällige Zeichenfolge, die vor dem Hashing hinzugefügt werden muss) und es in der Sockets-Variablen speichert. Anschließend überträgt er diesen Hash an den Client. Der Client nimmt das Benutzerkennwort, hasht es, fügt das Salz vom Server hinzu und hasht das Ganze, bevor er es an den Server überträgt. Dann wird es an den Server gesendet, der diesen Hash mit dem Hash vergleicht (Hash im DB + Salt). Soweit ich weiß, ist dies ein guter Ansatz, aber um fair zu sein, habe ich nicht viel zu diesem Thema gelesen und wenn ich mich in irgendetwas irre, würde ich gerne korrigiert werden :)
Verwenden Sie HTTP Digest - es sichert das Passwort sogar über http (aber die beste Verwendung wäre http Digest über https).
Wikipedia:
Die HTTP-Digest-Zugriffsauthentifizierung ist eine der vereinbarten Methoden, mit denen ein Webserver Anmeldeinformationen mit einem Webbenutzer aushandeln kann (unter Verwendung des HTTP-Protokolls). Die Digest-Authentifizierung soll die unverschlüsselte Verwendung der Standardzugriffsauthentifizierung ersetzen und die sichere Feststellung der Benutzeridentität ermöglichen, ohne dass ein Kennwort im Klartext über das Netzwerk gesendet werden muss. Die Digest-Authentifizierung ist im Grunde eine Anwendung von kryptografischem MD5-Hashing unter Verwendung von Nonce-Werten, um eine Kryptoanalyse zu verhindern.
Link: http://en.wikipedia.org/wiki/Digest_access_authentication
Wenn Sie eine "echte" Verwendung sehen möchten, können Sie sich phpMyID ansehen - einen PHP-OpenID-Anbieter, der die http-Digest-Authentifizierung http://siege.org/phpmyid.php verwendet
.. oder Sie könnten von den PHP-Auth-Beispielen unter http://php.net/manual/en/features.http-auth.php ausgehen
Http Digest RFC: http://www.faqs.org/rfcs/rfc2617
Nach meinen Tests unterstützen es alle modernen Browser ...
Wenn Sie ein Klartextkennwort über HTTPS durch ein Hash-Kennwort über HTTP ersetzen möchten, fragen Sie nach Problemen. HTTPS generiert beim Öffnen eines Kommunikationskanals einen zufälligen, gemeinsam genutzten Transaktionsschlüssel. Das ist schwer zu knacken, da Sie sich so ziemlich darauf beschränken, den gemeinsam genutzten Schlüssel, der für eine (relativ) kurzfristige Transaktion verwendet wird, brutal zu erzwingen. Während Ihr Hash nur beschnuppert, offline geschaltet und in einem Regenbogentisch nachgeschlagen oder einfach über einen langen Zeitraum gezwungen werden kann.
Eine über HTTPS gesendete grundlegende clientseitige Kennwortverschleierung (kein Hash) hat jedoch einen gewissen Wert. Wenn ich mich nicht irre, wird diese Technik tatsächlich von einigen Banken angewendet. Der Zweck dieser Technik besteht nicht darin, das Passwort vor dem Schnüffeln über das Kabel zu schützen. Vielmehr soll verhindert werden, dass das Kennwort für dumme Spionagetools und Browser-Plug-Ins verwendet werden kann, die nur jede angezeigte HTTPS-GET / POST-Anforderung abrufen. Ich habe eine Protokolldatei gesehen, die von einer schädlichen Website erfasst wurde und 400 MB zufällige GET / POST-Transaktionen enthielt, die aus Benutzersitzungen erfasst wurden. Sie können sich vorstellen, dass Websites, die nur HTTPS verwenden, mit Klartextkennwörtern im Protokoll angezeigt werden, aber auch Websites mit sehr grundlegender Verschleierung (ROT13) werden mit Kennwörtern angezeigt, die nicht sofort verwendet werden.
Wenn Sie mit einem https-Server verbunden sind, sollte der Datenstrom zwischen Server und Browser verschlüsselt werden. Die Daten sind nur einfacher Text vor dem Senden und nach dem Empfang. Wikipedia-Artikel
Haftungsausschluss: Ich bin kein Sicherheitsexperte - und ich poste in der Hoffnung, dass andere meine Position als übermäßig vorsichtig oder verbesserungsfähig kritisieren und ich daraus lernen werde. Vor diesem Hintergrund möchte ich nur betonen, dass Hashing, wenn es Ihren Client verlässt, nicht bedeutet, dass Sie kein Hash im Backend benötigen, bevor Sie es in die Datenbank aufnehmen.
Tue beides
Mach beides, weil:
Das Hashing auf der Überfahrt hilft dabei, Transportschwachstellen abzudecken. Wenn die SSL-Verbindung gefährdet ist, kann das unformatierte Kennwort immer noch nicht angezeigt werden. Es spielt keine Rolle, ob Sie sich als autorisierte Benutzer ausgeben können, aber es schützt Ihre Benutzer davor, dass ihre Passwörter in Verbindung mit ihrer E-Mail gelesen werden. Die meisten Benutzer befolgen nicht die bewährten Methoden und verwenden für viele ihrer Konten dasselbe Kennwort. Dies kann eine ernsthafte Sicherheitslücke für Ihre Besucher darstellen.
Wenn jemand irgendwie in der Lage war, Passwörter aus der Datenbank zu lesen (dies passiert, denken Sie an SQL Injection), kann er immer noch keine privilegierten Aktionen ausführen, die sich als Benutzer über meine API ausgeben. Dies liegt an der Hash-Asymmetrie. Selbst wenn sie den in Ihrer Datenbank gespeicherten Hash kennen, kennen sie den ursprünglichen Schlüssel, mit dem er erstellt wurde, nicht. Dies wird von Ihrer Authentifizierungs-Middleware zur Authentifizierung verwendet. Aus diesem Grund sollten Sie Ihren Hash-Speicher immer salzen.
Zugegeben, sie könnten viel anderen Schaden anrichten, wenn sie freie Hand hätten, um zu lesen, was sie von Ihrer Datenbank wollen.
Ich möchte hier nur betonen, dass, wenn Sie sich entscheiden, den Schlüssel vor der Abreise von Ihren Kunden zu hashen, dies nicht ausreicht - das Backend-Hashing ist imo viel wichtiger und deshalb: Wenn jemand Datenverkehr von Ihnen abfängt Client, dann sehen sie den Inhalt des password
Feldes. Ob dies ein Hash oder ein einfacher Text ist, spielt keine Rolle - sie können ihn wörtlich kopieren, um sich als autorisierter Client auszugeben. (Es sei denn, Sie befolgen die Schritte, die @ user3299591 beschreibt, und ich empfehle Ihnen, dies zu tun.) Das Hashing der DB-Spalte ist dagegen eine Notwendigkeit und überhaupt nicht schwer zu implementieren.
Ersetzt SSL / TLS nicht das Nonce? Ich sehe keinen Mehrwert dafür, da SSL / TLS auch vor Wiederholungsangriffen schützt.
Es wäre tatsächlich weniger sicher, das Passwort zu hashen und über einen unverschlüsselten Kanal zu senden. Sie werden Ihren Hashing-Algorithmus auf dem Client verfügbar machen. Hacker könnten einfach den Hash des Passworts schnüffeln und ihn später zum Hacken verwenden.
Durch die Verwendung von HTTPS verhindern Sie, dass ein Hacker das Kennwort aus einer einzigen Quelle erhält, da HTTPS zwei Kanäle verwendet, die beide verschlüsselt sind.
Ob es einen Vorteil gibt und ob es mehr (oder weniger) sicher ist, hängt wirklich von der Implementierung ab. Es gibt wohl einige Vorteile, aber wenn Sie es schlecht implementieren, können Sie definitiv eine Lösung erstellen, die weniger sicher ist als die Übergabe eines Klartext-Passworts.
Dies kann aus der Perspektive von zwei Arten von Angriffen betrachtet werden - einer mit Zugriff auf den Netzwerkverkehr und einer mit Zugriff auf die Datenbank.
Wenn Ihr Angreifer die Klartextversion des Netzwerkverkehrs abfangen kann, ist das Anzeigen eines Hash des Kennworts sicherer als das Anzeigen des Kennworts im Klartext. Obwohl sich der Angreifer weiterhin mit diesem Hash bei Ihrem Server anmelden könnte, wäre ein Brute-Force-Crack (manchmal vorberechnet) dieses Hash erforderlich, um das Kennwort zu ermitteln, das auf anderen Systemen nützlich sein könnte. Menschen sollten auf verschiedenen Systemen unterschiedliche Passwörter verwenden, dies jedoch häufig nicht.
Wenn ein Angreifer Zugriff auf die Datenbank erhalten hat, möglicherweise durch eine Kopie eines Backups, möchten Sie sicherstellen, dass Sie sich nicht nur mit diesem Wissen anmelden können. Wenn Sie beispielsweise einen mit dem Anmeldenamen gesalzenen Hash als gespeichert hash(login_name+password)
und denselben Hash vom Client zum direkten Vergleich übergeben haben, kann der Angreifer zufällig einen Benutzer auswählen, den aus der Datenbank gelesenen Hash senden und sich als anmelden dieser Benutzer, ohne das Passwort zu kennen, erhöht den Umfang der Verletzung. In diesem Fall wäre das Senden des Kennworts im Klartext sicherer gewesen, da der Angreifer den Klartext kennen müsste, um sich anzumelden, selbst wenn er eine Kopie der Datenbank hätte. Hier ist die Implementierung entscheidend. Unabhängig davon, ob Sie ein Klartextkennwort oder einen clientseitigen Hash dieses Kennworts senden, sollten Sie diesen Wert auf der Serverseite hashen und diesen Hash mit dem im Benutzerdatensatz gespeicherten Hash vergleichen.
Zu beachtende Konzepte: