Signatur
Beschreibung
Diese Funktion implementiert Authenticated Encryption with Associated Data (AEAD) auf Basis von ChaCha20 (Stromchiffre) und Poly1305 (MAC). Das bedeutet: Die Nachricht wird verschlüsselt und gleichzeitig mit einem Authentifizierungs-Tag versehen, das sicherstellt, dass weder der Geheimtext noch die zusätzlichen Daten ($additional_data) unbemerkt verändert werden können.
$additional_data (auch associated data genannt) werden nicht verschlüsselt, sondern nur authentifiziert. Dies eignet sich z. B. für Protokoll-Header oder Versions-Informationen, die im Klartext mitgesendet werden sollen, aber vor Manipulation geschützt sein müssen.
Der Rückgabewert enthält den Geheimtext gefolgt von einem 16-Byte-Poly1305-Tag als binären String. Diese Variante verwendet eine 64-Bit-Nonce (8 Byte) und ist für Umgebungen gedacht, in denen die originale ChaCha20-Poly1305-Spezifikation (nicht die IETF-Variante mit 96-Bit-Nonce) benötigt wird. Für die meisten neuen Projekte empfiehlt sich sodium_crypto_aead_chacha20poly1305_ietf_encrypt().
Ein kryptografisch zufälliger und eindeutiger Nonce je Nachricht ist zwingend erforderlich. Die Wiederverwendung eines Nonce mit demselben Schlüssel bricht die Sicherheit vollständig. Schlüssel und Nonce sollten ausschließlich über die entsprechenden Sodium-Hilfsfunktionen erzeugt werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $message Pflicht | string | Die zu verschlüsselnde Klartextnachricht als binärer String beliebiger Länge. | |
| $additional_data Pflicht | string | Zusätzliche Daten, die authentifiziert, aber nicht verschlüsselt werden (z. B. Header-Felder). Kann ein leerer String '' sein, wenn keine zusätzlichen Daten benötigt werden. |
|
| $nonce Pflicht | string | Einmalig zu verwendender Nonce als binärer String der Länge SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES (8 Byte). Muss für jede Verschlüsselung mit demselben Schlüssel einzigartig sein. |
|
| $key Pflicht | string | Geheimer Schlüssel der Länge SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES (32 Byte), idealer Weise erzeugt mit sodium_crypto_aead_chacha20poly1305_keygen(). |
Rückgabewert
$message) gefolgt von einem 16-Byte-Poly1305-Authentifizierungs-Tag. Die Gesamtlänge beträgt also strlen($message) + SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES.Beispiele
Nachricht verschlüsseln und anschließend entschlüsseln
<?php
// Schlüssel und Nonce erzeugen
$key = sodium_crypto_aead_chacha20poly1305_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES);
$message = 'Geheime Nachricht';
$additional_data = 'v1'; // z. B. Protokoll-Version, wird nicht verschlüsselt
// Verschlüsseln
$ciphertext = sodium_crypto_aead_chacha20poly1305_encrypt(
$message,
$additional_data,
$nonce,
$key
);
echo 'Geheimtext (hex): ' . bin2hex($ciphertext) . PHP_EOL;
// Entschlüsseln und verifizieren
$plaintext = sodium_crypto_aead_chacha20poly1305_decrypt(
$ciphertext,
$additional_data,
$nonce,
$key
);
if ($plaintext === false) {
echo 'Authentifizierung fehlgeschlagen!' . PHP_EOL;
} else {
echo 'Entschlüsselt: ' . $plaintext . PHP_EOL;
}
// Schlüssel sicher aus dem Speicher löschen
sodium_memzero($key);
Schutz von API-Tokens mit zusätzlichen Metadaten
<?php
// Einmalige Erzeugung und sichere Speicherung des Schlüssels
$key = sodium_crypto_aead_chacha20poly1305_keygen();
// $key würde in der Praxis aus einem sicheren Schlüssel-Speicher geladen
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES);
$token = 'supersecret-api-token-12345';
$additional_data = json_encode(['user_id' => 42, 'issued_at' => time()]);
$encrypted = sodium_crypto_aead_chacha20poly1305_encrypt(
$token,
$additional_data,
$nonce,
$key
);
// Nonce + verschlüsselte Daten zusammen speichern/übertragen
$payload = base64_encode($nonce . $encrypted);
echo 'Payload (Base64): ' . $payload . PHP_EOL;
// Beim Empfang: Nonce extrahieren und entschlüsseln
$decoded = base64_decode($payload);
$nonce_len = SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES;
$nonce_recv = substr($decoded, 0, $nonce_len);
$cipher = substr($decoded, $nonce_len);
$decrypted = sodium_crypto_aead_chacha20poly1305_decrypt(
$cipher,
$additional_data,
$nonce_recv,
$key
);
echo 'Token: ' . ($decrypted !== false ? $decrypted : 'Fehler') . PHP_EOL;
sodium_memzero($key);
// Wichtig · Fallstricke
Nonce-Einzigartigkeit ist kritisch: Wird derselbe Nonce mit demselben Schlüssel für zwei verschiedene Nachrichten verwendet, kann ein Angreifer den Schlüsselstrom ableiten und beide Klartexte sowie zukünftige Nachrichten entschlüsseln. Verwende immer random_bytes() oder einen sicheren Zähler zur Nonce-Erzeugung.
Varianten-Unterschied: Diese Funktion (ohne _ietf) verwendet eine 64-Bit-Nonce (8 Byte). Die IETF-Variante sodium_crypto_aead_chacha20poly1305_ietf_encrypt() verwendet eine 96-Bit-Nonce (12 Byte) und ist RFC 8439-konform. Für neue Projekte wird die IETF-Variante empfohlen, da sie mit mehr Bibliotheken interoperabel ist.
Schlüsselverwaltung: Schlüssel sollten nach Verwendung mit sodium_memzero() aus dem Speicher gelöscht werden, um das Risiko von Speicher-Dumps zu minimieren.
Kein Passwort als Schlüssel: Verwende niemals direkt ein Passwort als $key. Leite stattdessen mit sodium_crypto_pwhash() einen kryptografisch starken Schlüssel ab.