wake-up-neo.net

Verwenden Sie die Funktionen password_hash und password_verify von PHP 5.5

Angenommen, ich wollte ein Passwort für einen Benutzer speichern. Wäre dies der richtige Weg, um dies mit der Funktion password_hash() von PHP 5.5) zu tun (oder mit dieser Version für PHP 5.3.7+: https://github.com/ircmaxell/password_compat )?

$options = array("cost" => 10, "salt" => uniqid());
$hash = password_hash($password, PASSWORD_BCRYPT, $options);

Dann würde ich tun:

mysql_query("INSERT INTO users(username,password, salt) VALUES($username, $hash, " . $options['salt']);

In die Datenbank einfügen.

Dann zur Überprüfung:

$row = mysql_fetch_assoc(mysql_query("SELECT salt FROM users WHERE id=$userid"));
$salt = $row["salt"];
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10, "salt" => $salt));

if (password_verify($password, $hash) {
    // Verified
}
32
Doug Smith

Wenn Sie die Probleme mit Ihren Datenbankanweisungen vorerst ignorieren, beantworte ich die Frage zu password_hash.

Kurz gesagt, nein, so machst du es nicht. Sie möchten das Salz nicht alleine aufbewahren, Sie sollten sowohl den Hash als auch das Salz aufbewahren und dann beide zur Bestätigung des Kennworts verwenden. password_hash Gibt einen String zurück, der beide enthält.

Die Funktion password_hash Gibt eine Zeichenfolge zurück, die sowohl den Hash als auch das Salt enthält. So:

$hashAndSalt = password_hash($password, PASSWORD_BCRYPT);
// Insert $hashAndSalt into database against user

Dann zur Überprüfung:

// Fetch hash+salt from database, place in $hashAndSalt variable
// and then to verify $password:
if (password_verify($password, $hashAndSalt)) {
   // Verified
}

Wie aus den Kommentaren hervorgeht, sollten Sie bei Interesse an Sicherheit auch mysqli (ext/mysql Ist in PHP5.5 veraltet) und den folgenden Artikel zur SQL-Injection lesen: http://php.net/manual/en/security.database.sql-injection.php

59
Pete

Die Verwendung Ihres eigenen Salzes wird nicht empfohlen und ab PHP 7, dessen Verwendung wird nicht mehr empfohlen . Um zu verstehen, warum, der Autor von password_hash hat diese Gedanken geteilt (Link nicht mehr vorhanden)

Eines ist mir völlig klar geworden: Die Salzoption ist gefährlich. Ich habe noch keine einzige Verwendung der Salzoption gesehen, die sogar anständig war. Jede Verwendung reicht von fehlerhafter (Übergabe von mt_Rand () - Ausgabe) über gefährliche (statische Zeichenfolgen) bis verrückt (Übergabe des Kennworts als eigenes Salt).

Ich bin zu dem Schluss gekommen, dass ich nicht denke, dass wir Benutzern erlauben sollten, das Salz zu spezifizieren.

Er hat sogar machte diesen Kommentar in SO chat darauf hingewiesen, wie schlecht es sein kann, sein eigenes Salz zu verteilen

11
Machavity

Beachten Sie dies von php.net

Warnung

Die Option salt ist seit PHP 7.0.0 veraltet. Es wird jetzt bevorzugt, einfach das standardmäßig generierte Salt zu verwenden.

Fazit? Vergessen Sie Salz Option.

Das wäre völlig ausreichend password_hash('password', PASSWORD_DEFAULT) * (oder _BCRYPT)

7
Spooky

Sie sollten kein eigenes Salz eingeben, lassen Sie das Salz leer, die Funktion erzeugt ein gutes zufälliges Salz.

Fügen Sie die gesamte von der Funktion zurückgegebene Zeichenfolge in die Datenbank (oder Datei oder was auch immer Sie verwenden) ein. Es enthält: ID des Algorithmus, Kosten, Salt (22 Zeichen) und Hash-Passwort.

Die gesamte Zeichenfolge ist erforderlich, um password_verify () zu verwenden. Salt ist zufällig und kann nicht in die falschen Hände geraten (mit gehashtem Passwort). Dies verhindert (oder erschwert) die Verwendung fertiger Sets generierter Listen von Passwörtern und Hashes - Rainbow-Tabellen.

Sie sollten erwägen, Kostenparameter hinzuzufügen. Standard (wenn weggelassen) ist 1 - wenn höher, dann Funktion Berechne Hash länger. Erhöhen der Kosten um 1, doppelte Zeit, um einen Hash zu generieren (und somit die Zeit zu verlängern, die zum Auflösen des Passworts erforderlich ist)

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10));

sie sollten diesen Parameter basierend auf der Geschwindigkeitsprüfung auf Ihrem Server einstellen. Es wird empfohlen, dass die Funktion 100 ms + ausführt (einige bevorzugen 250 ms). Normalerweise sind Kosten = 10 oder 11 eine gute Wahl (im Jahr 2015).

Um die Sicherheit zu erhöhen, sollten Sie Kennwörtern eine lange (50-60 Zeichen sind eine gute Wahl) geheime Zeichenfolge hinzufügen. bevor Sie password_hash () oder password_verify () verwenden.

$secret_string = '[email protected]#[email protected]#$234';
$password  = trim($_POST['user_password']) . $secret_string;
// here use password_* function

Achtung Wenn Sie PASSWORD_BCRYPT für den Parameter algo verwenden, wird der Kennwortparameter auf eine maximale Länge von 72 Zeichen gekürzt.

Wenn $ password länger als 72 Zeichen ist und Sie 73 oder 90 Zeichen ändern oder hinzufügen, wird der Hash nicht geändert. Optional sollte $ secret_string am Ende stehen (nach dem Passwort des Benutzers und nicht davor).

5
Adam