Signatur
Beschreibung
sodium_crypto_stream_xor verknüpft die übergebene Nachricht per XOR mit einem aus Nonce und Schlüssel erzeugten Pseudozufalls-Keystream (XSalsa20). Da XOR sein eigenes Gegenteil ist, dient dieselbe Funktion sowohl zur Ver- als auch zur Entschlüsselung: Dasselbe Nonce und denselben Schlüssel auf den Geheimtext angewendet liefert wieder den Klartext.
Wichtig: Diese Funktion bietet keine Authentifizierung. Ein Angreifer kann den Geheimtext unbemerkt manipulieren. Für authentifizierte Verschlüsselung sollte stattdessen sodium_crypto_secretbox (XSalsa20-Poly1305) oder sodium_crypto_aead_* verwendet werden. sodium_crypto_stream_xor ist nur dann sinnvoll, wenn Authentizität und Integrität auf anderem Weg sichergestellt werden.
Das Nonce muss exakt SODIUM_CRYPTO_STREAM_NONCEBYTES Bytes (24 Byte) lang sein und darf für dieselbe Schlüssel-Nonce-Kombination niemals wiederverwendet werden. Ein sicheres Nonce kann mit random_bytes(SODIUM_CRYPTO_STREAM_NONCEBYTES) erzeugt werden. Der Schlüssel muss exakt SODIUM_CRYPTO_STREAM_KEYBYTES Bytes (32 Byte) lang sein.
Typische Einsatzfälle sind Protokolle, die ein separates MAC-Layer verwenden, sowie didaktische oder fortgeschrittene kryptografische Konstruktionen, bei denen die nackte Stream-Cipher benötigt wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $message Pflicht | string | Die zu verschlüsselnde (oder zu entschlüsselnde) Nachricht beliebiger Länge. | |
| $nonce Pflicht | string | Ein einmaliges Zufallswert (Number-used-once) von genau SODIUM_CRYPTO_STREAM_NONCEBYTES (24) Bytes. Darf pro Schlüssel niemals wiederverwendet werden. |
|
| $key Pflicht | string | Der geheime Schlüssel von genau SODIUM_CRYPTO_STREAM_KEYBYTES (32) Bytes. Kann mit sodium_crypto_stream_keygen() erzeugt werden. |
Rückgabewert
$message. Bei einem Fehler (z. B. falsche Nonce- oder Schlüssellänge) wird eine SodiumException geworfen.Beispiele
Einfache Ver- und Entschlüsselung einer Nachricht
<?php
$key = sodium_crypto_stream_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_NONCEBYTES);
$plaintext = 'Geheime Nachricht';
// Verschlüsseln
$ciphertext = sodium_crypto_stream_xor($plaintext, $nonce, $key);
echo 'Verschlüsselt (hex): ' . bin2hex($ciphertext) . PHP_EOL;
// Entschlüsseln (dieselbe Funktion, dieselben Parameter)
$decrypted = sodium_crypto_stream_xor($ciphertext, $nonce, $key);
echo 'Entschlüsselt: ' . $decrypted . PHP_EOL;
// Speicher bereinigen
sodium_memzero($key);
Kombination mit einem separaten HMAC für Authentifizierung
<?php
// HINWEIS: Nur zur Demonstration – bevorzuge sodium_crypto_secretbox in der Praxis.
$key = sodium_crypto_stream_keygen();
$hmacKey = random_bytes(32);
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_NONCEBYTES);
$plaintext = 'Nachricht mit externem MAC';
// Verschlüsseln
$ciphertext = sodium_crypto_stream_xor($plaintext, $nonce, $key);
// MAC über Nonce + Geheimtext berechnen (Encrypt-then-MAC)
$mac = hash_hmac('sha256', $nonce . $ciphertext, $hmacKey, true);
// Übertragen: $nonce, $ciphertext, $mac
// Empfängerseite: MAC prüfen
$expectedMac = hash_hmac('sha256', $nonce . $ciphertext, $hmacKey, true);
if (!hash_equals($expectedMac, $mac)) {
throw new RuntimeException('MAC-Prüfung fehlgeschlagen – Daten manipuliert!');
}
$decrypted = sodium_crypto_stream_xor($ciphertext, $nonce, $key);
echo $decrypted . PHP_EOL;
sodium_memzero($key);
sodium_memzero($hmacKey);
// Wichtig · Fallstricke
Sicherheitswarnung – Nonce-Wiederverwendung: Wird dasselbe Nonce mit demselben Schlüssel für zwei verschiedene Nachrichten verwendet, kann ein Angreifer durch XOR der beiden Geheimtexte den XOR der Klartexte erhalten. Dies kompromittiert die Vertraulichkeit vollständig (two-time pad-Angriff).
Keine Integrität oder Authentizität: Da kein MAC berechnet wird, kann ein Angreifer Bits im Geheimtext gezielt kippen, ohne dass dies erkannt wird. In der Praxis sollte fast immer sodium_crypto_secretbox bevorzugt werden.
Die Funktion wirft eine SodiumException, wenn Nonce oder Schlüssel nicht die korrekte Länge haben. Konstanten: SODIUM_CRYPTO_STREAM_NONCEBYTES = 24, SODIUM_CRYPTO_STREAM_KEYBYTES = 32.