Signatur
Beschreibung
sodium_crypto_stream_xchacha20_xor verschlüsselt eine beliebig lange Nachricht mittels des XChaCha20-Stromchiffres (eine Erweiterung von ChaCha20 mit 192-Bit-Nonce). Die Funktion XOR-verknüpft den Klartext mit einem aus Nonce und Schlüssel erzeugten Pseudozufalls-Keystream. Das Ergebnis ist ein Geheimtext gleicher Länge wie die Eingabe.
Wichtig: Diese Funktion bietet keine Authentifizierung (MAC). Ein Angreifer kann den Geheimtext unbemerkt manipulieren (Bit-Flipping-Attacke). Für die meisten Anwendungsfälle sollte stattdessen sodium_crypto_aead_xchacha20poly1305_ietf_encrypt verwendet werden, das zusätzlich einen Authentifizierungs-Tag erzeugt.
Der Einsatz ist sinnvoll, wenn Authentifizierung auf einer anderen Ebene (z. B. durch eine übergeordnete Signatur oder ein externes HMAC) bereits sichergestellt ist, oder wenn ausschließlich Vertraulichkeit ohne Integritätsschutz benötigt wird (z. B. beim Verschlüsseln eines Datenstroms, der separat authentifiziert wird).
Der Nonce muss exakt SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES (24 Bytes) lang sein und darf für denselben Schlüssel niemals wiederverwendet werden. Der Schlüssel muss SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES (32 Bytes) lang sein und geheim gehalten werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $message Pflicht | string | Die zu verschlüsselnde Klartextnachricht (beliebige Länge, auch binär). | |
| $nonce Pflicht | string | Ein 24-Byte-Nonce (SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES). Muss pro Schlüssel einmalig sein; am besten zufällig generiert mit random_bytes(24). |
|
| $key Pflicht | string | Der 32-Byte-Geheimschlüssel (SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES), erzeugt z. B. mit sodium_crypto_stream_xchacha20_keygen(). |
Rückgabewert
$message). Bei einem Fehler (z. B. falsche Parameterlängen) wird false zurückgegeben bzw. eine SodiumException geworfen.Beispiele
Einfache Verschlüsselung und Entschlüsselung
<?php
// Schlüssel und Nonce generieren
$key = sodium_crypto_stream_xchacha20_keygen(); // 32 Bytes
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES); // 24 Bytes
$plaintext = 'Geheime Nachricht, die verschlüsselt werden soll.';
// Verschlüsseln
$ciphertext = sodium_crypto_stream_xchacha20_xor($plaintext, $nonce, $key);
echo 'Geheimtext (hex): ' . bin2hex($ciphertext) . PHP_EOL;
// Entschlüsseln (dieselbe Funktion mit denselben Parametern)
$decrypted = sodium_crypto_stream_xchacha20_xor($ciphertext, $nonce, $key);
echo 'Klartext: ' . $decrypted . PHP_EOL;
// Speicher bereinigen
sodium_memzero($key);
Verschlüsselung eines Datenstroms mit separat gespeichertem Nonce
<?php
$key = sodium_crypto_stream_xchacha20_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES);
$data = 'Sensible Protokolldaten: ' . date('Y-m-d H:i:s');
$ciphertext = sodium_crypto_stream_xchacha20_xor($data, $nonce, $key);
// Nonce wird unverschlüsselt übertragen/gespeichert; Geheimtext separat
$package = base64_encode($nonce . $ciphertext);
echo 'Paket (Base64): ' . $package . PHP_EOL;
// Entpacken auf Empfängerseite
$raw = base64_decode($package);
$nonceLen = SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES;
$nonce2 = substr($raw, 0, $nonceLen);
$cipher2 = substr($raw, $nonceLen);
$recovered = sodium_crypto_stream_xchacha20_xor($cipher2, $nonce2, $key);
echo 'Wiederhergestellt: ' . $recovered . PHP_EOL;
sodium_memzero($key);
// Wichtig · Fallstricke
Sicherheitswarnung – keine Authentifizierung: XChaCha20-XOR bietet keinerlei Integritätsschutz. Wird derselbe Nonce mit demselben Schlüssel für zwei verschiedene Nachrichten verwendet, kann ein Angreifer durch XOR beider Geheimtexte Rückschlüsse auf die Klartexte ziehen (Two-Time-Pad-Angriff). Für den Regelfall sollte sodium_crypto_aead_xchacha20poly1305_ietf_encrypt verwendet werden.
Nonce-Einmaligkeit: Der 24-Byte-Nonce ist groß genug, um ihn mit random_bytes(24) sicher zufällig zu wählen, ohne Kollisionen befürchten zu müssen. Er muss zusammen mit dem Geheimtext gespeichert oder übertragen werden (er ist nicht geheim).
Schlüsselsicherheit: Den Schlüssel nach Gebrauch mit sodium_memzero($key) aus dem Speicher löschen, um ihn nicht länger als nötig im Prozessspeicher zu halten.