Frage Benutzer-Passwörter bereinigen


Wie kann ich von Benutzern bereitgestellte Kennwörter umgehen oder bereinigen, bevor ich sie hasse und in meiner Datenbank ablege?

Wenn PHP-Entwickler die Verwendung von Kennwörtern für Sicherheitszwecke in Erwägung ziehen, denken sie oft an diese Kennwörter, wie sie es auch bei anderen vom Benutzer bereitgestellten Daten tun würden. Dieses Thema taucht häufig in PHP-Fragen auf, die sich auf das Speichern von Passwörtern beziehen. Der Entwickler möchte das Passwort oft mit Funktionen wie z escape_string()(in verschiedenen Iterationen), htmlspecialchars(), addslashes() und andere vor dem Hashing und Speichern in der Datenbank.


76
2018-04-14 16:08


Ursprung


Antworten:


Sie sollten nie entkommen, trimmen oder irgendeinen anderen Bereinigungsmechanismus für Passwörter verwenden, die Sie mit PHP hashen password_hash() Aus einer Reihe von Gründen, die größte davon ist, weil zusätzliche Bereinigung des Kennworts unnötigen zusätzlichen Code erfordert.

Sie werden argumentieren (und Sie sehen es in jedem Beitrag, wo Benutzerdaten zur Verwendung in Ihren Systemen akzeptiert werden), dass wir alle Benutzereingaben bereinigen sollten und Sie für jede andere Information, die wir von unseren Benutzern akzeptieren, geeignet wären. Passwörter sind unterschiedlich. Hash-Kennwörter können keine SQL-Injection-Bedrohung bieten, da die Zeichenfolge vor dem Speichern in der Datenbank in Hash umgewandelt wird.

Der Vorgang des Hashing eines Kennworts besteht darin, das Kennwort sicher in Ihrer Datenbank zu speichern. Die Hash-Funktion gibt keinen Bytes eine besondere Bedeutung, so dass aus Sicherheitsgründen keine Bereinigung der Eingabe erforderlich ist

Wenn du den Mantren folgst, Benutzern zu erlauben, das zu verwenden Passwörter / Phrasen sie wünschen und du Kennwörter nicht begrenzenDurch die Angabe einer beliebigen Länge, einer beliebigen Anzahl von Leerzeichen und Sonderzeichen kann das Passwort / die Passphrase geschützt werden, unabhängig davon, was im Passwort enthalten ist. Ab sofort der gebräuchlichste Hash (der Standard), PASSWORD_BCRYPT, wandelt das Passwort in eine 60 Zeichen breite Zeichenfolge um, die ein zufälliges Salz enthält, zusammen mit der gehashten Passwort-Information und den Kosten (die algorithmischen Kosten für die Erstellung des Hash):

PASSWORD_BCRYPT wird verwendet, um neue Passwort-Hashes mit dem CRYPT_BLOWFISH-Algorithmus zu erstellen. Dies führt immer zu einem Hash, der das Crypt-Format "$ 2y $" verwendet, das immer 60 Zeichen breit ist.

Die Speicherplatzanforderungen zum Speichern des Hashs unterliegen Änderungen, da der Funktion verschiedene Hashing-Methoden hinzugefügt werden. Daher ist es immer besser, den Spaltentyp für den gespeicherten Hash zu vergrößern, wie z VARCHAR(255) oder TEXT.

Sie könnten eine vollständige SQL-Abfrage als Ihr Kennwort verwenden und es wäre Hash-Code, wodurch es von der SQL-Engine nicht ausführbar wäre.

SELECT * FROM `users`;

Könnte gehashed werden $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G

Lassen Sie uns sehen, wie verschiedene Desinfektionsverfahren das Passwort beeinflussen -

Das Passwort ist I'm a "dessert topping" & a <floor wax>! (Am Ende des Passwortes befinden sich 5 Leerzeichen, die hier nicht angezeigt werden.)

Wenn wir die folgenden Methoden zum Trimmen anwenden, erhalten wir einige unterschiedliche Ergebnisse:

var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));

Ergebnisse:

string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // double quotes, ampersand and braces have been changed
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>!     " // escape characters have been added
string(34) "I'm a "dessert topping" & a !     " // looks like we have something missing

Was passiert, wenn wir diese senden? password_hash()? Sie alle werden gehackt, genau wie die Abfrage oben getan hat. Das Problem tritt auf, wenn Sie versuchen, das Kennwort zu bestätigen. Wenn wir eine oder mehrere dieser Methoden anwenden, müssen wir sie erneut anwenden, bevor wir sie miteinander vergleichen password_verify(). Folgendes würde fehlschlagen:

password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query

Sie müssten das gepostete Passwort über die von Ihnen gewählte Bereinigungsmethode ausführen, bevor Sie das Ergebnis der Passwortverifizierung verwenden. Es ist eine unnötige Reihe von Schritten und wird den Hash nicht besser machen.


Verwenden einer PHP-Version weniger als 5.5? Du kannst den ... benutzen password_hash()  Kompatibilitätspaket.

Du solltest es wirklich nicht benutzen MD5-Passwort-Hashes.


88
2018-04-14 16:08



Bevor Sie das Passwort hashen, sollten Sie es wie in beschrieben normalisieren Abschnitt 4 von RFC 7613. Bestimmtes:

  1. Zusätzliche Zuordnungsregel: Alle Instanzen von Nicht-ASCII-Speicherplatz MÜSSEN sein      auf ASCII-Raum abgebildet (U + 0020); Ein Nicht-ASCII-Raum ist ein beliebiger Unicode      Codepunkt mit einer Unicode - Allgemeinkategorie "Zs" (mit der      Ausnahme von U + 0020).

und:

  1. Normalisierungsregel: Unicode-Normalisierungsform C (NFC) MUSS sein      auf alle Zeichen angewendet.

Dadurch wird sichergestellt, dass das Kennwort immer dann akzeptiert wird, wenn der Benutzer dasselbe Kennwort eingibt, aber eine andere Eingabemethode verwendet.


31
2018-04-14 16:20