Signatur
Beschreibung
hash_pbkdf2() implementiert den PBKDF2-Algorithmus (RFC 2898), der ein Passwort und ein Salt durch eine wählbare Hash-Funktion leitet und dabei eine konfigurierbare Anzahl von Iterationen durchläuft. Das Ergebnis ist ein abgeleiteter Schlüssel definierter Länge, der deutlich sicherer gegen Brute-Force-Angriffe ist als ein einfacher Hash.
Der Hauptanwendungsfall ist die sichere Ableitung von Verschlüsselungsschlüsseln aus Passwörtern, beispielsweise für symmetrische Verschlüsselung oder das Speichern von Passwort-Hashes in Datenbanken. Die hohe Iterationszahl erhöht den Rechenaufwand für Angreifer erheblich, während legitime Anwendungen nur einen einzigen Ableitungsvorgang durchführen müssen.
Für die reine Passwort-Speicherung empfiehlt PHP seit Version 5.5.0 bevorzugt password_hash() mit PASSWORD_BCRYPT oder PASSWORD_ARGON2ID, da diese Funktionen Salt und Iterationen automatisch verwalten. hash_pbkdf2() ist hingegen ideal, wenn ein Schlüssel mit bestimmter Länge für Verschlüsselungsoperationen (z. B. AES-256) abgeleitet werden muss.
Das Salt sollte kryptografisch zufällig und ausreichend lang sein (mindestens 16 Byte), erzeugt beispielsweise mit random_bytes(). Die Wahl der Iterationszahl sollte so hoch gewählt werden, dass die Berechnung auf der Zielplattform mindestens 100–350 ms dauert.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $algo Pflicht | string | Name des Hash-Algorithmus, z. B. 'sha256', 'sha512' oder 'sha3-256'. Alle von hash_algos() zurückgelieferten Algorithmen sind verwendbar. |
|
| $password Pflicht | string | Das Passwort, aus dem der Schlüssel abgeleitet werden soll. | |
| $salt Pflicht | string | Ein kryptografisch zufälliges Salt, das die Eindeutigkeit der Ableitung sicherstellt. Empfohlen: mindestens 16 Byte, erzeugt mit random_bytes(16). |
|
| $iterations Pflicht | int | Anzahl der Iterationen der internen Hash-Funktion. Höhere Werte erhöhen die Sicherheit gegen Brute-Force-Angriffe, erhöhen jedoch auch die Rechenzeit. Typische Werte: 100.000–600.000 für SHA-256. | |
| $length | int | 0 | Gewünschte Länge des abgeleiteten Schlüssels in Byte (bei $binary = false in hexadezimalen Zeichen). Bei 0 wird die volle Ausgabelänge des gewählten Algorithmus verwendet. |
| $binary | bool | false | Ist true, wird der Rückgabewert als Binär-String zurückgegeben; bei false (Standard) als Hexadezimal-String in Kleinbuchstaben. |
Rückgabewert
$binary = true). Wirft eine ValueError-Exception (PHP 8) bzw. einen E_WARNING-Fehler (PHP 7 und älter), wenn der Algorithmus unbekannt ist, $iterations kleiner als 1 ist oder $length negativ ist.Beispiele
AES-256-Schlüssel aus Passwort ableiten
<?php
// Zufälliges Salt erzeugen und sicher speichern
$salt = random_bytes(16);
// PBKDF2 mit SHA-256, 300.000 Iterationen, 32 Byte (= 256 Bit) für AES-256
$key = hash_pbkdf2('sha256', 'meinGeheimesPasswort', $salt, 300000, 32, true);
echo 'Schlüssellänge: ' . strlen($key) . ' Byte' . PHP_EOL;
echo 'Schlüssel (hex): ' . bin2hex($key) . PHP_EOL;
// Salt für spätere Wiederverwendung speichern (z. B. in Datenbank)
$saltHex = bin2hex($salt);
echo 'Salt (hex): ' . $saltHex . PHP_EOL;
Passwort-Hash speichern und verifizieren
<?php
function createPasswordHash(string $password): array
{
$salt = random_bytes(16);
$hash = hash_pbkdf2('sha512', $password, $salt, 210000, 64, false);
return [
'hash' => $hash,
'salt' => bin2hex($salt),
'iterations' => 210000,
'algo' => 'sha512',
];
}
function verifyPassword(string $password, array $stored): bool
{
$salt = hex2bin($stored['salt']);
$computed = hash_pbkdf2(
$stored['algo'],
$password,
$salt,
$stored['iterations'],
64,
false
);
// Timing-sicherer Vergleich
return hash_equals($stored['hash'], $computed);
}
// Erstmalig speichern
$record = createPasswordHash('SuperGeheim123!');
var_dump(verifyPassword('SuperGeheim123!', $record)); // true
var_dump(verifyPassword('FalschesPasswort', $record)); // false
// Wichtig · Fallstricke
Sicherheitshinweis – Timing-Angriffe: Beim Vergleich eines berechneten Hashes mit einem gespeicherten Hash immer hash_equals() verwenden, da herkömmliche Zeichenkettenvergleiche (===, strcmp) anfällig für Timing-Angriffe sind.
Salt: Das Salt darf niemals fest im Quellcode stehen oder wiederverwendet werden. Es muss zusammen mit dem Hash gespeichert werden, damit die Verifikation später möglich ist. Das Salt muss kein Geheimnis sein – seine Aufgabe ist es lediglich, Rainbow-Table-Angriffe zu verhindern.
Iterationszahl: Die empfohlene Iterationszahl steigt mit der Rechenleistung moderner Hardware. OWASP empfiehlt für SHA-256 mindestens 600.000 Iterationen (Stand 2023). Passe den Wert regelmäßig an und speichere ihn zusammen mit dem Hash, damit er bei zukünftigen Änderungen beibehalten werden kann.
Passwort-Speicherung vs. Schlüsselableitung: Für das bloße Speichern von Passwörtern in einer Datenbank ist password_hash() mit PASSWORD_ARGON2ID die modernere und komfortablere Wahl. hash_pbkdf2() ist bevorzugt einzusetzen, wenn ein Schlüssel fixer Länge für kryptografische Operationen wie AES oder HMAC benötigt wird.
Fehlerbehandlung (PHP 8+): Ungültige Argumente (unbekannter Algorithmus, $iterations < 1, $length < 0) werfen einen ValueError.