Start · Sprachen · PHP · Referenz · password_needs_rehash

password_needs_rehash

Funktion

Prüft, ob ein bestehender Passwort-Hash mit dem angegebenen Algorithmus und den Optionen übereinstimmt und ein erneutes Hashen nötig ist.

seit PHP 5.5.0 Kategorie: crypto

Signatur

password_needs_rehash(string $hash, string|int|null $algo, array $options = []): bool

Beschreibung

password_needs_rehash() vergleicht einen vorhandenen Passwort-Hash mit dem gewünschten Algorithmus und den übergebenen Optionen (z. B. cost bei Bcrypt). Gibt die Funktion true zurück, stimmt der gespeicherte Hash nicht mehr mit den aktuellen Anforderungen überein und sollte bei der nächsten erfolgreichen Anmeldung des Benutzers neu generiert werden.

Typischer Anwendungsfall ist ein Login-Prozess: Nach der Passwort-Überprüfung mit password_verify() wird password_needs_rehash() aufgerufen. Falls true zurückgegeben wird, erzeugt man mit password_hash() einen neuen Hash und speichert diesen in der Datenbank. So kann man schrittweise auf einen stärkeren Algorithmus oder höhere Kosten migrieren, ohne alle Passwörter auf einmal neu zu hashen.

Die Funktion gibt auch true zurück, wenn der Hash mit einem anderen Algorithmus erzeugt wurde, z. B. wenn man von PASSWORD_BCRYPT auf PASSWORD_ARGON2ID wechselt. false bedeutet, dass kein erneutes Hashen notwendig ist.

Seit PHP 8.0.0 akzeptiert der Parameter $algo auch null, was dem Standardalgorithmus entspricht (PASSWORD_DEFAULT).

Parameter

Name Typ Default Beschreibung
$hash Pflicht string Der zu prüfende Passwort-Hash, typischerweise aus der Datenbank gelesen.
$algo Pflicht string|int|null Der gewünschte Hashing-Algorithmus, z. B. PASSWORD_BCRYPT, PASSWORD_ARGON2I, PASSWORD_ARGON2ID oder PASSWORD_DEFAULT. Seit PHP 8.0 ist auch null erlaubt (entspricht PASSWORD_DEFAULT).
$options array [] Optionales assoziatives Array mit algorithmusspezifischen Optionen, z. B. ['cost' => 12] für Bcrypt oder ['memory_cost' => 65536, 'time_cost' => 4, 'threads' => 2] für Argon2.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn der Hash erneuert werden sollte (Algorithmus oder Optionen stimmen nicht überein), andernfalls false.

Beispiele

Passwort beim Login bei Bedarf neu hashen

<?php
// Simulierter Login-Prozess
$passwortEingabe = $_POST['password'] ?? '';
$gespeicherterHash = hole_hash_aus_db($benutzer_id); // z. B. aus der Datenbank

$algorithmus = PASSWORD_BCRYPT;
$optionen = ['cost' => 12];

if (password_verify($passwortEingabe, $gespeicherterHash)) {
    echo 'Anmeldung erfolgreich.';

    // Prüfen, ob der Hash aktualisiert werden muss
    if (password_needs_rehash($gespeicherterHash, $algorithmus, $optionen)) {
        $neuerHash = password_hash($passwortEingabe, $algorithmus, $optionen);
        speichere_hash_in_db($benutzer_id, $neuerHash); // Neuen Hash speichern
        echo ' Passwort-Hash wurde aktualisiert.';
    }
} else {
    echo 'Falsches Passwort.';
}
Anmeldung erfolgreich. Passwort-Hash wurde aktualisiert.

Migration von Bcrypt auf Argon2ID

<?php
// Alter Bcrypt-Hash (cost 10)
$alterHash = password_hash('geheim123', PASSWORD_BCRYPT, ['cost' => 10]);

// Neues Ziel: Argon2ID
$zielAlgo = PASSWORD_ARGON2ID;

if (password_needs_rehash($alterHash, $zielAlgo)) {
    echo 'Hash muss erneuert werden — anderer Algorithmus erkannt.';
} else {
    echo 'Kein Rehash notwendig.';
}
Hash muss erneuert werden — anderer Algorithmus erkannt.

Erhöhte Bcrypt-Kosten erkennen

<?php
// Bestehender Hash mit cost 10
$hash = password_hash('meinPasswort', PASSWORD_BCRYPT, ['cost' => 10]);

// Wir wollen jetzt cost 13 verwenden
if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 13])) {
    echo 'Cost-Faktor hat sich erhöht — Rehash erforderlich.';
} else {
    echo 'Kein Rehash nötig.';
}
Cost-Faktor hat sich erhöht — Rehash erforderlich.

// Wichtig · Fallstricke

Sicherheitshinweis: Das erneute Hashen darf nur nach einer erfolgreichen Überprüfung mit password_verify() erfolgen, da hierfür das Klartextpasswort benötigt wird. Das Klartextpasswort sollte niemals dauerhaft gespeichert werden.

Timing-Angriffe: Verwende stets password_verify() zum Vergleich von Passwörtern, da diese Funktion timing-sicher ist. Rohe Zeichenkettenvergleiche wie === sind unsicher.

PASSWORD_DEFAULT: Da sich PASSWORD_DEFAULT in zukünftigen PHP-Versionen ändern kann, empfiehlt es sich, password_needs_rehash() in den Login-Prozess zu integrieren, damit bestehende Hashes automatisch auf den neuen Standard migriert werden.