Signatur
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
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);
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);
// 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()oderpassword_hash(). - Bei Speichermangel oder ungültigen Parametern wird eine
SodiumExceptiongeworfen.