HAFTUNGSAUSSCHLUSS : Diese Antwort wurde im Jahr 2008 verfasst.
Seitdem hat PHP uns Folgendes beschert password_hash
y password_verify
und sind seit ihrer Einführung die empfohlene Methode zum Hashing und zur Überprüfung von Passwörtern.
Die Theorie der Antwort ist aber immer noch eine gute Lektüre.
TL;DR
Was man nicht tun sollte
- Schränken Sie nicht ein, welche Zeichen Benutzer für Passwörter eingeben können. Das machen nur Idioten.
- Schränken Sie die Länge eines Passworts nicht ein. Wenn Ihre Benutzer einen Satz mit "supercalifragilisticexpialidocious" wünschen, sollten Sie sie nicht daran hindern, ihn zu verwenden.
- HTML- und Sonderzeichen im Kennwort dürfen nicht entfernt oder umgangen werden.
- Speichern Sie das Passwort Ihres Benutzers niemals im Klartext.
- Senden Sie niemals ein Passwort per E-Mail an Ihren Benutzer Es sei denn, sie haben ihren verloren und Sie haben einen Ersatz geschickt.
- Loggen Sie niemals Passwörter in irgendeiner Form.
- Hosten Sie niemals Passwörter mit SHA1 oder MD5 oder sogar SHA256! Moderne Cracker kann 60 bzw. 180 Milliarden Hashes/Sekunde übersteigen.
- Nicht mischen bcrypt und mit dem roh Ausgabe von hash() verwenden Sie entweder die Hex-Ausgabe oder base64_encodieren Sie sie. (Dies gilt für alle Eingaben, die einen abtrünnigen
\0
was die Sicherheit ernsthaft beeinträchtigen kann).
Dos
- Verwenden Sie scrypt, wenn Sie können; bcrypt, wenn Sie nicht können.
- Verwenden Sie PBKDF2, wenn Sie weder bcrypt noch scrypt mit SHA2-Hashes verwenden können.
- Setzen Sie die Passwörter aller Benutzer zurück, wenn die Datenbank kompromittiert wurde.
- Führen Sie eine vernünftige Mindestlänge von 8-10 Zeichen ein, und verlangen Sie mindestens einen Großbuchstaben, einen Kleinbuchstaben, eine Zahl und ein Symbol. Dadurch wird die Entropie des Kennworts erhöht, was es wiederum schwerer macht, es zu knacken. (Siehe den Abschnitt "Was macht ein gutes Passwort aus?" für eine Diskussion).
Warum überhaupt Hash-Passwörter?
Das Ziel hinter dem Hashing von Kennwörtern ist einfach: Verhinderung des böswilligen Zugriffs auf Benutzerkonten durch Kompromittierung der Datenbank. Ziel des Passwort-Hashings ist es also, Hacker oder Cracker abzuschrecken, indem es sie zu viel Zeit oder Geld kostet, die Klartextpasswörter zu berechnen. Und Zeit/Kosten sind die besten Abschreckungsmittel in Ihrem Arsenal.
Ein weiterer Grund, warum Sie einen guten, robusten Hash für ein Benutzerkonto benötigen, ist, dass Sie genug Zeit haben, um alle Kennwörter im System zu ändern. Wenn Ihre Datenbank kompromittiert wird, brauchen Sie genug Zeit, um am wenigsten das System sperren, wenn nicht sogar alle Passwörter in der Datenbank ändern.
Jeremiah Grossman, CTO von Whitehat Security, erklärt im White Hat Security Blog nach einer kürzlichen Passwortwiederherstellung, bei der sein Passwortschutz mit roher Gewalt geknackt werden musste:
Interessanterweise habe ich in diesem Alptraum eine Menge über das Knacken, Speichern und die Komplexität von Passwörtern gelernt, was ich nicht wusste. Ich habe begriffen, warum die Speicherung von Passwörtern viel wichtiger ist als die Komplexität der Passwörter. Wenn Sie nicht wissen, wie Ihr Passwort gespeichert wird, können Sie sich nur auf die Komplexität verlassen. Für Passwort- und Krypto-Profis mag dies allgemein bekannt sein, aber für den durchschnittlichen InfoSec- oder Web-Sicherheitsexperten bezweifle ich es stark.
(Hervorhebung von mir.)
Was macht eine gut Passwort überhaupt?
Entropie . (Nicht, dass ich Randalls Standpunkt uneingeschränkt teile).
Kurz gesagt, die Entropie gibt an, wie groß die Variation innerhalb eines Kennworts ist. Wenn ein Passwort nur aus lateinischen Kleinbuchstaben besteht, sind das nur 26 Zeichen. Das ist nicht sehr abwechslungsreich. Alphanumerische Kennwörter sind mit 36 Zeichen besser. Aber wenn man Groß- und Kleinbuchstaben und Symbole zulässt, sind es ungefähr 96 Zeichen. Das ist viel besser als nur Buchstaben. Ein Problem ist, dass wir, um unsere Kennwörter einprägsam zu machen, Muster einfügen, was die Entropie verringert. Huch!
Die Passwort-Entropie ist angenähert leicht. Bei Verwendung aller ASCII-Zeichen (etwa 96 tippbare Zeichen) ergibt sich eine Entropie von 6,6 pro Zeichen, was bei 8 Zeichen für ein Kennwort immer noch zu wenig ist (52,679 Bits Entropie) für die künftige Sicherheit. Aber die gute Nachricht ist: Längere Kennwörter und Kennwörter mit Unicode-Zeichen erhöhen die Entropie eines Kennworts und machen es schwieriger, es zu knacken.
Eine längere Diskussion über die Entropie von Passwörtern findet sich auf der Website Krypto StackExchange Standort. Eine gute Google-Suche wird ebenfalls viele Ergebnisse liefern.
In den Kommentaren habe ich mit @popnoodles gesprochen, der darauf hinwies, dass Durchsetzung von Eine Kennwortrichtlinie der Länge X mit X Buchstaben, Zahlen, Symbolen usw. kann die Entropie tatsächlich verringern, indem sie das Kennwortschema berechenbarer macht. Ich stimme zu. Zufälligkeit, und zwar so zufällig wie möglich, ist immer die sicherste, aber am wenigsten einprägsame Lösung.
Soweit ich das beurteilen kann, ist die Entwicklung des besten Passworts der Welt eine Zwickmühle. Entweder ist es nicht einprägsam, zu vorhersehbar, zu kurz, zu viele Unicode-Zeichen (schwer einzugeben auf einem Windows-/Mobilgerät), zu lang usw. Kein Kennwort ist wirklich gut genug für unsere Zwecke, also müssen wir es schützen, als wäre es in Fort Knox.
Bewährte Praktiken
Bcrypt und scrypt sind die derzeit besten Praktiken. Scrypt wird mit der Zeit besser sein als bcrypt, aber es hat sich noch nicht als Standard unter Linux/Unix oder auf Webservern durchgesetzt, und es wurden noch keine detaillierten Bewertungen seines Algorithmus veröffentlicht. Dennoch sieht die Zukunft des Algorithmus vielversprechend aus. Wenn Sie mit Ruby arbeiten, gibt es ein Scrypt-Edelstein die Ihnen helfen werden, und Node.js hat jetzt seine eigene scrypt Paket. Sie können Scrypt in PHP entweder über das Scrypt Erweiterung oder die Libsodium Erweiterung (beide sind in PECL verfügbar).
Ich empfehle dringend, die Dokumentation für das Kryptofunktion wenn Sie verstehen wollen, wie man bcrypt benutzt, oder wenn Sie einen gut Umschlag oder verwenden Sie etwas wie PHPASS für eine eher ältere Implementierung. Ich empfehle mindestens 12 Runden bcrypt, wenn nicht sogar 15 bis 18.
Ich habe meine Meinung über die Verwendung von bcrypt geändert, als ich erfuhr, dass bcrypt nur den Blowfish-Schlüsselplan mit einem variablen Kostenmechanismus verwendet. Mit letzterem können Sie die Kosten für das Brute-Force-Verfahren eines Passworts erhöhen, indem Sie den ohnehin schon teuren Blowfish-Schlüsselplan erhöhen.
Durchschnittliche Praktiken
Ich kann mir diese Situation fast nicht mehr vorstellen. PHPASS unterstützt PHP 3.0.18 bis 5.3, so dass es auf fast jeder erdenklichen Installation verwendet werden kann - und verwendet werden sollte, wenn Sie nicht mit Sicherheit wissen dass Ihre Umgebung bcrypt unterstützt.
Aber nehmen wir an, dass Sie bcrypt oder PHPASS überhaupt nicht verwenden können. Was dann?
Versuchen Sie eine Implementierung von PDKBF2 mit dem maximale Anzahl von Runden die Ihre Umgebung/Anwendung/Benutzerwahrnehmung tolerieren kann. Die niedrigste Zahl, die ich empfehlen würde, ist 2500 Runden. Achten Sie außerdem auf die Verwendung von hash_hmac() wenn sie verfügbar ist, um die Reproduktion des Vorgangs zu erschweren.
Künftige Praktiken
Mit PHP 5.5 wird eine Bibliothek mit umfassendem Passwortschutz die alle Schwierigkeiten bei der Arbeit mit bcrypt beseitigt. Während die meisten von uns mit PHP 5.2 und 5.3 in den meisten üblichen Umgebungen feststecken, insbesondere bei gemeinsam genutzten Hosts, hat @ircmaxell eine Kompatibilitätsschicht für die kommende API, die rückwärtskompatibel zu PHP 5.3.7 ist.
Kryptographie - Zusammenfassung & Haftungsausschluss
Die erforderliche Rechenleistung für die tatsächliche Riss ein gehashtes Passwort nicht existiert. Die einzige Möglichkeit für Computer, ein Kennwort zu "knacken", besteht darin, es neu zu erstellen und den zur Sicherung verwendeten Hash-Algorithmus zu simulieren. Die Geschwindigkeit des Hash-Algorithmus steht in einem linearen Verhältnis zu seiner Brute-Force-Fähigkeit. Schlimmer noch: Die meisten Hash-Algorithmen können leicht parallelisiert werden, um noch schneller zu werden. Aus diesem Grund sind kostspielige Verfahren wie bcrypt und scrypt so wichtig.
Sie können unmöglich alle Bedrohungen oder Angriffsmöglichkeiten vorhersehen und müssen daher Ihr Bestes tun, um Ihre Benutzer zu schützen. im Vorfeld . Wenn Sie das nicht tun, könnten Sie sogar die Tatsache übersehen, dass Sie angegriffen wurden, bis es zu spät ist... und Sie sind haftbar . Um diese Situation zu vermeiden, sollten Sie von Anfang an paranoid sein. Greifen Sie Ihre eigene Software (intern) an und versuchen Sie, Benutzeranmeldeinformationen zu stehlen, die Konten anderer Benutzer zu ändern oder auf deren Daten zuzugreifen. Wenn Sie die Sicherheit Ihres Systems nicht testen, können Sie niemandem außer sich selbst die Schuld geben.
Und schließlich: Ich bin kein Kryptograph. Alles, was ich gesagt habe, ist meine Meinung, aber ich denke, sie basiert auf dem guten alten gesunden Menschenverstand ... und viel Lesen. Denken Sie daran: Seien Sie so paranoid wie möglich, machen Sie das Eindringen so schwer wie möglich, und wenn Sie dann immer noch besorgt sind, wenden Sie sich an einen White-Hat-Hacker oder Kryptographen, um zu sehen, was sie zu Ihrem Code/System sagen.
14 Stimmen
openwall.com/phpass ist auch eine sehr gute Bibliothek
60 Stimmen
Md5 ist jetzt völlig unsicher
3 Stimmen
@NSAwesomeGuy Das hängt davon ab, wofür Sie es verwenden. Es ist trivial, ungesalzene MD5-Passwörter mit Rainbow-Match oder Brute-Force zu knacken, aber mit anständigem Salting ist es immer noch äußerst unpraktisch, eine Rainbow-Tabelle zum schnellen Knacken von Passwortsätzen zu erstellen, und Brute-Force ist ein No-Hoper.
15 Stimmen
PHP 5.5+ hat einen sicheren Passwort-Hash eingebaut php.net/manual/de/function.passwort-hash.php
0 Stimmen
php.net/faq.passwort
0 Stimmen
Wie man die Passwort-Hashing-Funktionen von PHP 5.5 verwendet
0 Stimmen
Siehe auch Openwalls Portables PHP-Passwort-Hashing-Framework (PHPass). Es ist gegen eine Reihe von häufigen Angriffen auf Benutzerpasswörter gehärtet.
0 Stimmen
Eingebaut seit v5.6 php.net/manual/de/function.passwort-hash.php