Beim Erstellen eines Benutzerauthentifizierungssystems ist ein sicherer Handling von Passwörtern ein Problem, auf das Entwickler achten müssen. Wenn Sie kennwörter falsch verglichen werden, kann das System Sicherheitsbedrohungen wie Timing -Angriffe unterliegen. PHP bietet einige integrierte Funktionen, mit denen wir die Passwortüberprüfung sicher verarbeiten können. Unter ihnen ist die Kombination von Crypt () und Hash_Equals () eine relativ sichere Art der Praxis.
Crypt () ist eine Verschlüsselungsfunktion von PHP, die zum Hash-Verschlüsselungskennwörter verwendet wird, basierend auf einem Algorithmus (wie Bcrypt , SHA-512 usw.). Seine Syntax ist wie folgt:
string crypt(string $string, string $salt)
Der Salzparameter bestimmt den Verschlüsselungsalgorithmus und sein Verhalten. Für moderne Anwendungen wird BCrypt empfohlen, und das entsprechende Salz kann automatisch mit den folgenden Methoden erzeugt werden:
$salt = '$2y$10$' . substr(strtr(base64_encode(random_bytes(16)), '+', '.'), 0, 22);
$hash = crypt('mypassword', $salt);
Viele Anfänger schreiben den folgenden Code, um Passwörter zu überprüfen:
if (crypt($inputPassword, $storedHash) == $storedHash) {
// Erfolgreich anmelden
}
Dies erscheint in der Funktion machbar, aber es besteht ein schwerwiegendes Sicherheitsrisiko - Timing -Angriff . Ein Angreifer kann den richtigen Kennwort -Hash nach und nach erraten, indem er den geringfügigen Unterschied in der Programmantwortzeit misst.
Um das Problem der Timing -Angriffe zu lösen, bietet PHP die Funktion von Hash_equals (), da 5.6 zwei Hash -Werte sicher verglichen werden:
bool hash_equals(string $known_string, string $user_string)
Es verwendet einen konstanten Zeitalgorithmus und kehrt basierend auf dem Inhalt der Zeichenfolge nicht im Voraus zurück, wodurch Zeitdifferenzleckage vermieden wird.
<?php
// Angenommen, wir erhalten den verschlüsselten Passwort -Hash aus der Datenbank
$storedHash = '$2y$10$9YzyYtVht3tcGEn.7PiF2OlRM0HDTrM7Z5D.yPi8hdm0fJeFVKH4K'; // Abhängig von crypt() Generiert bcrypt Hash
$inputPassword = $_POST['password'] ?? '';
// verwenden crypt() 对verwenden户输入的密码进行Hash,使verwenden存储Hash作为 salt
$inputHash = crypt($inputPassword, $storedHash);
// 使verwenden hash_equals() Sicherheitsvergleich
if (hash_equals($storedHash, $inputHash)) {
echo "Erfolgreich anmelden!";
} else {
echo "Fehlerkennwort!";
}
?>
Obwohl CryPT () weiterhin sicher zu verwenden ist, empfiehlt PHP -Offizieller, password_hash () und passwart_verify () zu verwenden, da sie den Algorithmusauswahl- und Sicherheitsvergleichsprozess zusammenfassen, sodass es einfacher und sicherer zu verwenden ist. Zum Beispiel:
// 创建密码Hash
$hash = password_hash('mypassword', PASSWORD_BCRYPT);
// Passwort überprüfen
if (password_verify($inputPassword, $hash)) {
echo "Überprüfung verabschiedet";
}
In einigen Szenarien (z. B. alte Systeme oder besonderen Bedürfnissen) ist die Kombination von Crypt () und Hash_Equals () immer noch eine akzeptable und sichere Lösung.
Vermeiden Sie die Verwendung von == oder === Vergleiche Passwort -Hashes;
Bei Verwendung von Crypt () Hash -Passwort müssen Sie Salz und Algorithmus korrekt auswählen (BCrypt wird empfohlen).
Verwenden Sie Hash_equals () für sichere Vergleiche, um Zeitanschläge zu verhindern.
Wenn es keinen bestimmten Grund gibt, wird empfohlen, Passage_hash () und passwart_verify () anstelle einer Kapselung mit niedriger Ebene zu verwenden.
Sicherheit ist keine Option, sondern eine Anforderung bei der Bearbeitung von Benutzerkennwörtern. Der korrekte Ansatz kann nicht nur die Privatsphäre der Benutzer schützen, sondern auch den Angriffswiderstand des gesamten Systems verbessern.