Start · Sprachen · PHP · Referenz · hash_pbkdf2

hash_pbkdf2

Funktion

Erzeugt einen kryptografischen Schlüssel aus einem Passwort mittels PBKDF2 (Password-Based Key Derivation Function 2).

seit PHP 5.5.0 Kategorie: crypto

Signatur

hash_pbkdf2(string $algo, string $password, string $salt, int $iterations, int $length = 0, bool $binary = false): string

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 Iterations­zahl 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 Iterations­zahl 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

Typ
string
Beschreibung
Der abgeleitete Schlüssel als Hexadezimal-String (Standardfall) oder als Binär-String (wenn $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;
Schlüssellänge: 32 Byte Schlüssel (hex): <64 hexadezimale Zeichen> Salt (hex): <32 hexadezimale Zeichen>

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
bool(true) bool(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.

Iterations­zahl: Die empfohlene Iterations­zahl 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.