Signatur
Beschreibung
Diese Funktion implementiert das AEAD-Verfahren (Authenticated Encryption with Additional Data) auf Basis von ChaCha20-Poly1305 in der IETF-Variante (RFC 8439). Die Nachricht wird sowohl verschlüsselt als auch mit einem Poly1305-Authentifizierungs-Tag versehen, sodass spätere Manipulation erkannt wird.
Der Unterschied zur nicht-IETF-Variante liegt im Nonce-Format: Die IETF-Variante verwendet einen 96-Bit-Nonce (12 Byte, siehe SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES), während die ursprüngliche libsodium-Variante einen 64-Bit-Nonce nutzt. Die IETF-Variante ist mit dem TLS 1.3 Standard kompatibel und wird für neue Systeme empfohlen.
Der Parameter $additional_data ermöglicht es, Metadaten (z. B. Header, Protokollversionen) in die Authentifizierung einzubeziehen, ohne sie zu verschlüsseln. Diese Daten werden beim Entschlüsseln zur Verifikation benötigt, erscheinen aber im Klartext im Chiffretext.
Für die Entschlüsselung steht die Gegenfunktion sodium_crypto_aead_chacha20poly1305_ietf_decrypt() zur Verfügung. Schlüssel und Nonce sollten stets mit den passenden Hilfsfunktionen der Sodium-Bibliothek erzeugt werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $message Pflicht | string | Die Klartextnachricht, die verschlüsselt werden soll. | |
| $additional_data Pflicht | string | Zusätzliche Daten, die nicht verschlüsselt, aber in die Authentifizierung einbezogen werden (kann ein leerer String '' sein, wenn keine zusätzlichen Daten benötigt werden). |
|
| $nonce Pflicht | string | Ein einmaliger 96-Bit-Nonce (12 Byte). Muss für jede Verschlüsselung mit demselben Schlüssel einzigartig sein. Erzeugen mit random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES). |
|
| $key Pflicht | string | Der geheime 256-Bit-Schlüssel (32 Byte). Erzeugen mit sodium_crypto_aead_chacha20poly1305_ietf_keygen(). |
Rückgabewert
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES (16 Byte) länger als die ursprüngliche Nachricht, da der Poly1305-Authentifizierungs-Tag angehängt wird. Bei einem Fehler wird eine SodiumException ausgelöst.Beispiele
Einfache Verschlüsselung und Entschlüsselung
<?php
// Schlüssel und Nonce erzeugen
$key = sodium_crypto_aead_chacha20poly1305_ietf_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES);
$message = 'Geheime Nachricht';
$additional_data = 'Protokoll-Header v1';
// Verschlüsseln
$ciphertext = sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
$message,
$additional_data,
$nonce,
$key
);
echo 'Chiffretext (hex): ' . bin2hex($ciphertext) . PHP_EOL;
// Entschlüsseln
$decrypted = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
$ciphertext,
$additional_data,
$nonce,
$key
);
if ($decrypted === false) {
echo 'Entschlüsselung fehlgeschlagen!';
} else {
echo 'Klartext: ' . $decrypted . PHP_EOL;
}
// Speicher bereinigen
sodium_memzero($key);
Sicherer Datei-Metadaten-Schutz mit Additional Data
<?php
// Schlüssel dauerhaft speichern (z. B. in Umgebungsvariable)
$key = sodium_crypto_aead_chacha20poly1305_ietf_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES);
// Metadaten, die den Kontext binden (nicht verschlüsselt, aber authentifiziert)
$additional_data = json_encode([
'user_id' => 42,
'version' => '1.0',
]);
$payload = json_encode(['creditCard' => '4111-1111-1111-1111', 'amount' => 99.99]);
$ciphertext = sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
$payload,
$additional_data,
$nonce,
$key
);
// Nonce und Ciphertext zusammen speichern (Nonce ist nicht geheim)
$stored = base64_encode($nonce . $ciphertext);
echo 'Gespeicherter Blob (Base64): ' . $stored . PHP_EOL;
// Später: Entschlüsseln
$raw = base64_decode($stored);
$nonce = substr($raw, 0, SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES);
$ciphertext = substr($raw, SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES);
$decrypted = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
$ciphertext,
$additional_data, // Muss identisch zur Verschlüsselung sein!
$nonce,
$key
);
echo 'Entschlüsselt: ' . $decrypted . PHP_EOL;
sodium_memzero($key);
// Wichtig · Fallstricke
Nonce-Wiederverwendung ist kritisch: Wird derselbe Nonce mit demselben Schlüssel für zwei verschiedene Nachrichten verwendet, kann ein Angreifer den Schlüsselstrom wiederherstellen und beide Nachrichten entschlüsseln. Nonces müssen daher immer zufällig oder monoton steigend (Zähler) sein.
Schlüsselverwaltung: Der Schlüssel darf niemals im Klartext gespeichert oder übertragen werden. Verwende sodium_memzero(), um den Schlüssel nach Verwendung aus dem Speicher zu löschen.
Additional Data: Wird beim Entschlüsseln ein anderer Wert für $additional_data übergeben als beim Verschlüsseln, schlägt die Authentifizierung fehl und sodium_crypto_aead_chacha20poly1305_ietf_decrypt() gibt false zurück. Das ist kein Fehler, sondern das gewünschte Verhalten zum Schutz vor Kontext-Verwechslung.
Keine zufällig generierten Nonces für Streams: Bei mehr als 232 Nachrichten mit demselben Schlüssel besteht statistisch die Gefahr einer Kollision bei zufälligen Nonces. In solchen Fällen sollte ein Zähler oder ein Schlüsselableitungsschema eingesetzt werden.