Start · Sprachen · PHP · Referenz · sodium_crypto_stream_xor

sodium_crypto_stream_xor

Funktion

Verschlüsselt oder entschlüsselt eine Nachricht mit XSalsa20-Stream-XOR, <strong>ohne</strong> Authentifizierung.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_stream_xor(string $message, string $nonce, string $key): string

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

Typ
string
Beschreibung
Gibt den verschlüsselten (oder entschlüsselten) Binär-String zurück. Die Länge ist identisch mit der Länge von $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);
Verschlüsselt (hex): <zufälliger Hex-String> Entschlüsselt: Geheime Nachricht

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);
Nachricht mit externem MAC

// 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.