Start · Sprachen · PHP · Referenz · sodium_crypto_pwhash

sodium_crypto_pwhash

Funktion

Leitet mit dem Argon2-Algorithmus einen kryptografisch sicheren Schlüssel aus einem Passwort und einem Salt ab.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_pwhash(int $length, string $password, string $salt, int $opslimit, int $memlimit, int $alg = SODIUM_CRYPTO_PWHASH_ALG_DEFAULT): string

Beschreibung

sodium_crypto_pwhash() ist eine Passwort-basierte Schlüsselableitungsfunktion (PBKDF) aus der libsodium-Bibliothek. Sie verwendet den Argon2-Algorithmus (standardmäßig Argon2id), der speziell dafür entwickelt wurde, Brute-Force- und Dictionary-Angriffe durch hohen Speicher- und Rechenaufwand zu erschweren. Das Ergebnis ist ein binärer Schlüssel beliebiger Länge, der z. B. für symmetrische Verschlüsselung verwendet werden kann.

Im Gegensatz zu sodium_crypto_pwhash_str(), die einen fertigen Passwort-Hash für die Speicherung erzeugt, dient sodium_crypto_pwhash() der Schlüsselableitung: Das Passwort wird in einen Schlüssel einer definierten Länge umgewandelt, etwa um damit Daten mit sodium_crypto_secretbox() oder sodium_crypto_aead_*-Funktionen zu verschlüsseln.

Die Parameter $opslimit und $memlimit steuern den Rechenaufwand und den Speicherverbrauch. Höhere Werte erhöhen die Sicherheit, verlängern aber die Ausführungszeit. Für interaktive Anwendungen empfehlen sich die Konstanten SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE und SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE; für sensiblere Anwendungen die _SENSITIVE-Varianten.

Das Salt muss für jede Schlüsselableitung zufällig und eindeutig sein. Es wird nicht geheim gehalten, muss aber zusammen mit den anderen Parametern gespeichert werden, um denselben Schlüssel später rekonstruieren zu können. Zur Erzeugung eines geeigneten Salts dient random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES).

Parameter

Name Typ Default Beschreibung
$length Pflicht int Gewünschte Länge des abgeleiteten Schlüssels in Bytes. Muss mindestens SODIUM_CRYPTO_PWHASH_BYTES_MIN und maximal SODIUM_CRYPTO_PWHASH_BYTES_MAX betragen.
$password Pflicht string Das Klartextpasswort, aus dem der Schlüssel abgeleitet wird. Sollte aus dem Speicher gelöscht werden, sobald es nicht mehr benötigt wird (sodium_memzero()).
$salt Pflicht string Ein zufälliges Salt der Länge SODIUM_CRYPTO_PWHASH_SALTBYTES (16 Bytes). Muss eindeutig pro Schlüsselableitung sein und zusammen mit dem abgeleiteten Schlüsselmaterial gespeichert werden.
$opslimit Pflicht int Maximale Anzahl der Rechenoperationen. Empfohlene Konstanten: SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE, SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE.
$memlimit Pflicht int Maximale Speichermenge in Bytes. Empfohlene Konstanten: SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE.
$alg int SODIUM_CRYPTO_PWHASH_ALG_DEFAULT Der zu verwendende Algorithmus. Mögliche Werte: SODIUM_CRYPTO_PWHASH_ALG_DEFAULT (Argon2id), SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 oder SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13.

Rückgabewert

Typ
string
Beschreibung
Gibt einen binären String der angegebenen Länge zurück, der als kryptografischer Schlüssel genutzt werden kann. Bei einem Fehler wird eine SodiumException ausgelöst.

Beispiele

Schlüssel aus Passwort ableiten und Daten verschlüsseln

<?php
// Salt erzeugen (nur beim ersten Mal; muss gespeichert werden!)
$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);

$password = 'MeinSicheresPasswort123!';

// Schlüssel mit interaktiven Parametern ableiten (32 Bytes für secretbox)
$key = sodium_crypto_pwhash(
    SODIUM_CRYPTO_SECRETBOX_KEYBYTES,
    $password,
    $salt,
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

// Nonce erzeugen
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

$plaintext = 'Geheime Nachricht';
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);

// Verschlüsselte Daten + Salt + Nonce für spätere Entschlüsselung speichern
$stored = base64_encode($salt . $nonce . $ciphertext);
echo "Verschlüsselt (Base64): " . $stored . PHP_EOL;

// Passwort aus dem Speicher löschen
sodium_memzero($password);
sodium_memzero($key);
Verschlüsselt (Base64): <zufälliger Base64-String>

Schlüssel wiederherstellen und Daten entschlüsseln

<?php
// Gespeicherte Daten wieder einlesen
$data = base64_decode($stored);

$saltLen   = SODIUM_CRYPTO_PWHASH_SALTBYTES;
$nonceLen  = SODIUM_CRYPTO_SECRETBOX_NONCEBYTES;

$salt       = substr($data, 0, $saltLen);
$nonce      = substr($data, $saltLen, $nonceLen);
$ciphertext = substr($data, $saltLen + $nonceLen);

$password = 'MeinSicheresPasswort123!';

// Schlüssel mit denselben Parametern und demselben Salt neu ableiten
$key = sodium_crypto_pwhash(
    SODIUM_CRYPTO_SECRETBOX_KEYBYTES,
    $password,
    $salt,
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);

if ($decrypted === false) {
    echo 'Entschlüsselung fehlgeschlagen – falsches Passwort oder manipulierte Daten.';
} else {
    echo 'Entschlüsselt: ' . $decrypted . PHP_EOL;
}

sodium_memzero($password);
sodium_memzero($key);
Entschlüsselt: Geheime Nachricht

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Das Salt muss für jede Schlüsselableitung einzigartig und zufällig sein. Verwenden Sie niemals dasselbe Salt für verschiedene Passwörter oder Zwecke.
  • Das Salt ist nicht geheim, muss aber persistent gespeichert werden, da ohne es derselbe Schlüssel nicht mehr reproduziert werden kann.
  • Passwörter und abgeleitete Schlüssel sollten nach der Verwendung mit sodium_memzero() aus dem Speicher gelöscht werden, um Side-Channel-Angriffe zu erschweren.
  • Verwenden Sie keine zu niedrigen $opslimit- oder $memlimit-Werte. Die _MIN-Konstanten sind nicht für den Produktionseinsatz geeignet.
  • Diese Funktion dient der Schlüsselableitung, nicht dem Speichern von Passwort-Hashes. Für letzteren Zweck verwenden Sie sodium_crypto_pwhash_str() oder password_hash().
  • Bei Speichermangel oder ungültigen Parametern wird eine SodiumException geworfen.