Hin und wieder höre ich den Rat "Verwenden Sie bcrypt zum Speichern von Passwörtern in PHP, bcrypt Regeln".
Aber was ist das bcrypt
? PHP bietet keine solchen Funktionen, Wikipedia plappert über ein Dienstprogramm zur Dateiverschlüsselung und Websuchen enthüllen nur einige Implementierungen von Blowfish in verschiedenen Sprachen. Jetzt ist Blowfish auch in PHP über verfügbar mcrypt
, aber wie hilft das beim Speichern von Passwörtern? Blowfish ist eine Allzweck-Chiffre, die auf zwei Arten funktioniert. Wenn es verschlüsselt werden könnte, kann es entschlüsselt werden. Passwörter benötigen eine Einweg-Hashing-Funktion.
Was ist die Erklärung?
bcrypt
ein Einweg-Hashing-Algorithmus im Vergleich zu einem Verschlüsselungsschema verwendet wird . Es gibt dieses ganze Missverständnis, das nur Blowfish ist, obwohl es tatsächlich einen völlig anderen Schlüsselplan gibt, der sicherstellt, dass einfacher Text nicht aus dem Chiffretext wiederhergestellt werden kann, ohne den Anfangszustand der Chiffre (Salz, Runden, Schlüssel) zu kennen.bcrypt
Antworten:
bcrypt
ist ein Hashing-Algorithmus, der mit Hardware skalierbar ist (über eine konfigurierbare Anzahl von Runden). Die Langsamkeit und die mehreren Runden stellen sicher, dass ein Angreifer massive Mittel und Hardware einsetzen muss, um Ihre Passwörter knacken zu können. Dazu kommen pro-Passwort Salze (bcrypt
BRAUCHT Salze) , und Sie können sicher sein , dass ein Angriff ohne entweder lächerliche Menge von Geldern oder Hardware praktisch nicht durchführbar ist.bcrypt
verwendet den Eksblowfish- Algorithmus zum Hashing von Passwörtern. Während die Verschlüsselungsphase von Eksblowfish und Blowfish genau gleich ist, stellt die Schlüsselzeitplanphase von Eksblowfish sicher, dass jeder nachfolgende Status sowohl von Salt als auch vom Schlüssel (Benutzerkennwort) abhängt und kein Status ohne Wissen von beiden vorberechnet werden kann. Aufgrund dieses Hauptunterschiedsbcrypt
handelt es sich um einen Einweg-Hashing-Algorithmus. Sie können das Nur-Text-Passwort nicht abrufen, ohne das Salz, die Runden und den Schlüssel (Passwort) bereits zu kennen . [ Quelle ]So verwenden Sie bcrypt:
Mit PHP> = 5.5-DEV
Passwort-Hashing-Funktionen wurden jetzt direkt in PHP> = 5.5 integriert . Sie können jetzt
password_hash()
einenbcrypt
Hash eines beliebigen Passworts erstellen :Um ein vom Benutzer angegebenes Kennwort anhand eines vorhandenen Hashs zu überprüfen, können Sie Folgendes verwenden
password_verify()
:Mit PHP> = 5.3.7, <5.5-DEV (auch RedHat PHP> = 5.3.3)
Es gibt eine Kompatibilitätsbibliothek auf GitHub erstellt auf den Quellcode der oben genannten Funktionen basieren ursprünglich in C geschrieben, die die gleiche Funktionalität zur Verfügung stellt. Sobald die Kompatibilitätsbibliothek installiert ist, ist die Verwendung dieselbe wie oben (abzüglich der Kurzarray-Notation, wenn Sie sich noch im Zweig 5.3.x befinden).
Verwenden von PHP <5.3.7 (DEPRECATED)
Sie können die
crypt()
Funktion verwenden, um bcrypt-Hashes von Eingabezeichenfolgen zu generieren. Diese Klasse kann automatisch Salze erzeugen und vorhandene Hashes anhand einer Eingabe überprüfen. Wenn Sie eine Version von PHP verwenden, die höher oder gleich 5.3.7 ist, wird dringend empfohlen, die integrierte Funktion oder die kompatible Bibliothek zu verwenden . Diese Alternative wird nur für historische Zwecke bereitgestellt.Sie können diesen Code folgendermaßen verwenden:
Alternativ können Sie auch das Portable PHP Hashing Framework verwenden .
quelle
mt_rand()
wird auch die aktuelle Zeit und die aktuelle Prozess-ID verwendet. Bitte sehen SieGENERATE_SEED()
in/ext/standard/php_rand.h
.crypt()
dann Peer-Review und Verifikation durchgeführt werden. Der obige Code ruft PHPs aufcrypt()
, die die POSIX-crypt()
Funktion aufrufen . Der obige Code bewirkt lediglich, dass vor dem Aufruf ein zufälliges Salt generiert wird (das nicht kryptografisch sicher sein muss, das Salt wird nicht als Geheimnis betrachtet)crypt()
. Vielleicht sollten Sie selbst ein wenig recherchieren, bevor Sie Wolf anrufen.crypt()
) unterliegt einer Sicherheitslücke vor 5.3.7 und ist nach 5.3.7 (geringfügig) ineffizient. Details zum relevanten Problem finden Sie hier . Bitte beachten Sie auch, dass die neue Passwort-Hashing-API ( abwärtskompatible Bibliothek ) jetzt die bevorzugte Methode zum Implementieren von bcrypt-Passwort-Hashing in Ihrer Anwendung ist.Sie möchten also bcrypt verwenden? Genial! Wie in anderen Bereichen der Kryptographie sollten Sie dies jedoch nicht selbst tun. Wenn Sie sich Gedanken über die Verwaltung von Schlüsseln, das Speichern von Salzen oder das Generieren von Zufallszahlen machen müssen, machen Sie es falsch.
Der Grund ist einfach: Es ist so einfach, bcrypt zu vermasseln . Wenn Sie sich fast jeden Code auf dieser Seite ansehen, werden Sie feststellen, dass mindestens eines dieser häufigen Probleme verletzt wird.
Seien Sie ehrlich, Kryptographie ist schwer.
Überlassen Sie es den Experten. Überlassen Sie es den Personen, deren Aufgabe es ist, diese Bibliotheken zu pflegen. Wenn Sie eine Entscheidung treffen müssen, machen Sie es falsch.
Verwenden Sie stattdessen einfach eine Bibliothek. Je nach Ihren Anforderungen gibt es mehrere.
Bibliotheken
Hier finden Sie eine Aufschlüsselung einiger der gängigsten APIs.
PHP 5.5 API - (Verfügbar für 5.3.7+)
Ab PHP 5.5 wird eine neue API zum Hashing von Passwörtern eingeführt. Es gibt auch eine Shim-Kompatibilitätsbibliothek, die (von mir) für 5.3.7+ verwaltet wird. Dies hat den Vorteil, dass es sich um eine von Experten überprüfte und einfach zu verwendende Implementierung handelt.
Wirklich, es soll extrem einfach sein.
Ressourcen:
Zend \ Crypt \ Password \ Bcrypt (5.3.2+)
Dies ist eine weitere API, die der von PHP 5.5 ähnelt und einen ähnlichen Zweck erfüllt.
Ressourcen:
PasswordLib
Dies ist ein etwas anderer Ansatz für das Passwort-Hashing. PasswordLib unterstützt nicht nur bcrypt, sondern auch eine Vielzahl von Hashing-Algorithmen. Dies ist vor allem in Kontexten nützlich, in denen Sie die Kompatibilität mit älteren und unterschiedlichen Systemen unterstützen müssen, die möglicherweise außerhalb Ihrer Kontrolle liegen. Es unterstützt eine große Anzahl von Hashing-Algorithmen. Und wird 5.3.2+ unterstützt
Verweise:
PHPASS
Dies ist eine Ebene, die bcrypt unterstützt, aber auch einen ziemlich starken Algorithmus unterstützt, der nützlich ist, wenn Sie keinen Zugriff auf PHP> = 5.3.2 haben ... Sie unterstützt tatsächlich PHP 3.0+ (obwohl nicht mit bcrypt).
Ressourcen
Hinweis: Verwenden Sie keine PHPASS-Alternativen, die nicht auf Openwall gehostet werden, sondern unterschiedliche Projekte !!!
Über BCrypt
Wenn Sie bemerken, gibt jede dieser Bibliotheken eine einzelne Zeichenfolge zurück. Das liegt daran, wie BCrypt intern funktioniert. Und dazu gibt es eine Menge Antworten. Hier ist eine Auswahl, die ich geschrieben habe und die ich hier nicht kopieren / einfügen werde, sondern auf Folgendes verweise:
md5
Passwörter zu bcryptEinpacken
Es gibt viele verschiedene Möglichkeiten. Welche Sie wählen, liegt bei Ihnen. Ich würde jedoch dringend empfehlen, dass Sie eine der oben genannten Bibliotheken verwenden, um dies für Sie zu erledigen .
Wenn Sie
crypt()
direkt verwenden, machen Sie wahrscheinlich etwas falsch. Wenn Ihr Code direkthash()
(odermd5()
odersha1()
) verwendet, machen Sie mit ziemlicher Sicherheit etwas falsch.Verwenden Sie einfach eine Bibliothek ...
quelle
mt_rand()
also eine ausreichend hohe Periode, aber der Startwert beträgt nur 32 Bit.mt_rand()
Wenn Sie also effektiv verwenden, sind Sie auf nur 32 Bit Entropie beschränkt. Dank des Geburtstagsproblems haben Sie eine 50% ige Kollisionswahrscheinlichkeit bei nur 7.000 erzeugten Salzen (weltweit). Dabcrypt
128 Bit Salz akzeptiert werden, ist es besser, eine Quelle zu verwenden, die alle 128 Bit liefern kann ;-). (bei 128 Bit, 50% Kollisionswahrscheinlichkeit bei 2e19 Hashes) ...mt_rand
unduniqid
(und damitlcg_value
undrand
) sind nicht die erste Wahl ...In Genug mit den Regenbogentabellen finden Sie viele Informationen : Was Sie über sichere Kennwortschemata oder das tragbare PHP-Kennwort-Hashing-Framework wissen müssen .
Das Ziel ist es, das Passwort mit etwas Langsamem zu hashen, damit jemand, der Ihre Passwortdatenbank erhält, beim Versuch, es brutal zu erzwingen, stirbt (eine Verzögerung von 10 ms, um ein Passwort zu überprüfen, ist nichts für Sie, viel für jemanden, der versucht, es brutal zu erzwingen). Bcrypt ist langsam und kann mit einem Parameter verwendet werden, um zu wählen, wie langsam es ist.
quelle
Sie können mit bcrypt einen Einweg-Hash erstellen, indem Sie die PHP-
crypt()
Funktion verwenden und ein geeignetes Blowfish-Salz eingeben. Das Wichtigste der gesamten Gleichung ist, dass A) der Algorithmus nicht kompromittiert wurde und B) Sie jedes Passwort richtig salzen . Verwenden Sie kein anwendungsweites Salz. Dadurch wird Ihre gesamte Anwendung für Angriffe von einem einzigen Satz von Rainbow-Tabellen aus geöffnet.PHP - Kryptofunktion
quelle
crypt()
Funktion, die verschiedene Passwort-Hashing-Funktionen unterstützt. Stellen Sie sicher, dass Sie nicht verwendenCRYPT_STD_DES
oderCRYPT_EXT_DES
- - einer der anderen unterstützten Typen ist in Ordnung (und enthält bcrypt unter dem NamenCRYPT_BLOWFISH
).crypt
macht mehrere Passwort-Hashes verfügbar, wobei bcrypt derCRYPT_BLOWFISH
Konstante entspricht. Bcrypt ist derzeit der stärkste Algorithmus, der von unterstützt wird,crypt
und einige andere, die es unterstützt, sind ziemlich schwach.Edit: 2013.01.15 - Wenn Ihr Server dies unterstützt, verwenden Sie stattdessen die Lösung von martinstoeckli .
Jeder möchte das komplizierter machen als es ist. Die crypt () -Funktion erledigt den größten Teil der Arbeit.
Beispiel:
Ich weiß, dass es offensichtlich sein sollte, aber bitte verwenden Sie nicht 'Passwort' als Ihr Passwort.
quelle
2y
anstelle von zu verwenden2a
.mcrypt_create_iv($size, MCRYPT_DEV_URANDOM)
als Quelle für das Salz.bcrypt
.mcrypt_create_iv(17, MCRYPT_DEV_URANDOM)
,str_replace('+', '.', base64_encode($rawSalt))
,$salt = substr($salt, 0, 22);
Version 5.5 von PHP bietet integrierte Unterstützung für BCrypt, die Funktionen
password_hash()
undpassword_verify()
. Eigentlich sind dies nur Wrapper um die Funktioncrypt()
und sollen die korrekte Verwendung erleichtern. Es sorgt für die Erzeugung eines sicheren zufälligen Salzes und liefert gute Standardwerte.Der einfachste Weg, diese Funktionen zu nutzen, ist:
Dieser Code hasht das Passwort mit BCrypt (Algorithmus
2y
), generiert ein zufälliges Salt aus der zufälligen Quelle des Betriebssystems und verwendet den Standardkostenparameter (im Moment ist dies 10). In der zweiten Zeile wird geprüft, ob das vom Benutzer eingegebene Passwort mit einem bereits gespeicherten Hashwert übereinstimmt.Wenn Sie den Kostenparameter ändern möchten, können Sie dies folgendermaßen tun: Erhöhen Sie den Kostenparameter um 1 und verdoppeln Sie die für die Berechnung des Hashwerts erforderliche Zeit:
Im Gegensatz zum
"cost"
Parameter ist es am besten, den"salt"
Parameter wegzulassen , da die Funktion bereits ihr Bestes tut, um ein kryptografisch sicheres Salz zu erstellen.Für PHP Version 5.3.7 und höher gibt es ein Kompatibilitätspaket desselben Autors, der die
password_hash()
Funktion erstellt hat. Für PHP - Versionen vor 5.3.7 gibt es keine Unterstützung fürcrypt()
mit2y
, die Unicode sicher BCrypt Algorithmus. Man könnte es stattdessen durch ersetzen2a
, was die beste Alternative für frühere PHP-Versionen ist.quelle
Aktuelles Denken: Hashes sollten am langsamsten verfügbar sein, nicht am schnellsten. Dies unterdrückt Regenbogentischangriffe .
Ebenfalls verwandt, aber vorsorglich: Ein Angreifer sollte niemals uneingeschränkten Zugriff auf Ihren Anmeldebildschirm haben. Um dies zu verhindern: Richten Sie eine IP-Adressverfolgungstabelle ein, die jeden Treffer zusammen mit dem URI aufzeichnet. Wenn in einem Zeitraum von fünf Minuten mehr als 5 Anmeldeversuche von derselben IP-Adresse ausgehen, blockieren Sie dies mit einer Erklärung. Ein sekundärer Ansatz besteht darin, ein zweistufiges Passwortschema zu haben, wie es Banken tun. Das Sperren von Fehlern im zweiten Durchgang erhöht die Sicherheit.
Zusammenfassung: Verlangsamen Sie den Angreifer mithilfe zeitaufwändiger Hash-Funktionen. Blockieren Sie außerdem zu viele Zugriffe auf Ihr Login und fügen Sie eine zweite Kennwortebene hinzu.
quelle
Hier ist eine aktualisierte Antwort auf diese alte Frage!
Der richtige Weg, um Passwörter in PHP seit 5.5 zu hashen, ist mit
password_hash()
, und der richtige Weg, sie zu überprüfen, ist mitpassword_verify()
, und dies gilt immer noch in PHP 8.0. Diese Funktionen verwenden standardmäßig bcrypt-Hashes, es wurden jedoch auch andere stärkere Algorithmen hinzugefügt. Sie können den Arbeitsfaktor (effektiv, wie "stark" die Verschlüsselung ist) über diepassword_hash
Parameter ändern .Obwohl bcrypt immer noch stark genug ist, gilt es nicht mehr als Stand der Technik . Mit den Varianten Argon2i, Argon2d und Argon2id ist ein besserer Satz von Passwort-Hash-Algorithmen namens Argon2 eingetroffen . Der Unterschied zwischen ihnen (wie hier beschrieben ):
Argon2i-Unterstützung wurde in PHP 7.2 hinzugefügt und Sie fordern dies folgendermaßen an:
und Argon2id-Unterstützung wurde in PHP 7.3 hinzugefügt:
Für die Überprüfung von Kennwörtern sind keine Änderungen erforderlich, da die resultierende Hash-Zeichenfolge Informationen darüber enthält, welche Algorithmen, Salt- und Arbeitsfaktoren bei der Erstellung verwendet wurden.
Ganz separat (und etwas redundant) bietet libsodium (hinzugefügt in PHP 7.2) auch Argon2-Hashing über die Funktionen
sodium_crypto_pwhash_str ()
undsodium_crypto_pwhash_str_verify()
, die ähnlich wie die integrierten PHP-Funktionen funktionieren. Ein möglicher Grund für die Verwendung dieser ist, dass PHP manchmal ohne libargon2 kompiliert werden kann, wodurch die Argon2-Algorithmen für die Funktion password_hash nicht verfügbar sind. PHP 7.2 und höher sollte immer libsodium aktiviert haben, aber möglicherweise nicht - aber es gibt zumindest zwei Möglichkeiten, wie Sie diesen Algorithmus verwenden können. So können Sie einen Argon2id-Hash mit libsodium erstellen (auch in PHP 7.2, das ansonsten keine Argon2id-Unterstützung bietet)):Beachten Sie, dass Sie ein Salz nicht manuell angeben können. Dies ist Teil des libsodium-Ethos. Erlauben Sie Benutzern nicht, Parameter auf Werte zu setzen, die die Sicherheit gefährden könnten. Beispielsweise hindert Sie nichts daran, eine leere Salt-Zeichenfolge an die PHP-
password_hash
Funktion zu übergeben. libsodium lässt dich nichts so Dummes tun!quelle
Für OAuth 2- Passwörter:
quelle
Wie wir alle wissen, ist das Speichern des Passworts im Klartext in der Datenbank nicht sicher. Das bcrypt ist eine Hashing-Passwort-Technik. Es wird verwendet, um die Passwortsicherheit aufzubauen. Eine der erstaunlichen Funktionen von bcrypt ist, dass es uns vor Hackern schützt. Es wird verwendet, um das Passwort vor Hacking-Angriffen zu schützen, da das Passwort in verschlüsselter Form gespeichert ist.
Mit der Funktion password_hash () wird ein neuer Passwort-Hash erstellt. Es verwendet einen starken und robusten Hashing-Algorithmus. Die Funktion password_hash () ist sehr gut mit der Funktion crypt () kompatibel. Daher können von crypt () erstellte Passwort-Hashes mit password_hash () verwendet werden und umgekehrt. Die Funktionen password_verify () und password_hash () sind nur die Wrapper um die Funktion crypt () und erleichtern die genaue Verwendung erheblich.
SYNTAX
Die folgenden Algorithmen werden derzeit von der Funktion password_hash () unterstützt:
PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I PASSWORD_ARGON2ID
Parameter: Diese Funktion akzeptiert drei Parameter, wie oben erwähnt und unten beschrieben:
Passwort : Hier wird das Passwort des Benutzers gespeichert. algo : Dies ist die Konstante des Passwortalgorithmus, die kontinuierlich verwendet wird, während der Algorithmus angegeben wird, der verwendet werden soll, wenn das Hashing des Passworts stattfindet. Optionen : Es ist ein assoziatives Array, das die Optionen enthält. Wenn dies entfernt wird und nicht enthalten ist, wird ein zufälliges Salz verwendet, und die Verwendung von Standardkosten erfolgt. Rückgabewert : Es gibt das Hash - Passwort auf Erfolg oder False bei Fehlern.
Beispiel :
Die folgenden Programme veranschaulichen die Funktion password_hash () in PHP:
AUSGABE
quelle