Start · Sprachen · PHP · Referenz · sodium_crypto_stream_xchacha20_xor

sodium_crypto_stream_xchacha20_xor

Funktion

Verschlüsselt eine Nachricht mit dem XChaCha20-Stromchiffre unter Verwendung von Nonce und geheimem Schlüssel, <strong>ohne</strong> Authentifizierung.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_stream_xchacha20_xor(string $message, string $nonce, string $key): string|false

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

Typ
string|false
Beschreibung
Gibt den verschlüsselten Geheimtext als Binär-String zurück (gleiche Länge wie $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);
Geheimtext (hex): <zufälliger Hex-String> Klartext: Geheime Nachricht, die verschlüsselt werden soll.

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);
Paket (Base64): <Base64-codierter String> Wiederhergestellt: Sensible Protokolldaten: <aktuelles Datum/Uhrzeit>

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