Start · Sprachen · PHP · Referenz · sodium_crypto_stream_xchacha20_xor_ic

sodium_crypto_stream_xchacha20_xor_ic

Funktion

Verschlüsselt eine Nachricht mit XChaCha20-Stream und Anfangszähler (ohne Authentifizierung).

seit PHP 8.1.0 Kategorie: crypto

Signatur

sodium_crypto_stream_xchacha20_xor_ic(string $message, string $nonce, int $counter, string $key): string

Beschreibung

sodium_crypto_stream_xchacha20_xor_ic ist eine Variante der XChaCha20-Stromverschlüsselung, die zusätzlich einen initialen Block-Zähler (initial counter, kurz ic) entgegennimmt. Dadurch lassen sich Nachrichten ab einem bestimmten Block-Offset verschlüsseln oder entschlüsseln, ohne den gesamten Datenstrom ab Byte 0 erzeugen zu müssen.

Die Funktion ist symmetrisch: Derselbe Aufruf mit identischen Parametern entschlüsselt einen zuvor verschlüsselten Chiffretext. Sie eignet sich daher für Szenarien, in denen Teilbereiche großer Datenmengen parallel oder unabhängig voneinander verarbeitet werden sollen – etwa beim segmentierten Verschlüsseln von Dateien.

Wichtig: Diese Funktion bietet keinerlei Authentifizierung oder Integritätsschutz. Ohne eine zusätzliche MAC- oder AEAD-Konstruktion (z. B. sodium_crypto_aead_xchacha20poly1305_ietf_encrypt) können manipulierte Chiffretexte nicht erkannt werden. Im Normalfall sollten AEAD-Primitiven bevorzugt werden.

Jede Kombination aus Nonce und Schlüssel darf nur für eine einzige Nachricht verwendet werden. Wiederverwendung derselben Nonce mit demselben Schlüssel bricht die Vertraulichkeit vollständig.

Parameter

Name Typ Default Beschreibung
$message Pflicht string Die Klartextnachricht, die verschlüsselt werden soll, bzw. der Chiffretext, der entschlüsselt werden soll. Die Länge des Rückgabewerts ist identisch mit der Länge dieser Eingabe.
$nonce Pflicht string Eine 192-Bit-Nonce (24 Byte). Muss für jede Nachricht eindeutig sein, die mit demselben Schlüssel verschlüsselt wird. Die Konstante SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES (= 24) gibt die erforderliche Länge an.
$counter Pflicht int Der initiale Block-Zähler. Gibt an, bei welchem 64-Byte-Block des Schlüsselstroms die Verschlüsselung beginnt. Ein Wert von 0 entspricht dem normalen Verhalten ohne Offset.
$key Pflicht string Der geheime 256-Bit-Schlüssel (32 Byte). Sollte mit sodium_crypto_stream_xchacha20_keygen() erzeugt werden. Die Konstante SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES (= 32) gibt die erforderliche Länge an.

Rückgabewert

Typ
string
Beschreibung
Gibt den verschlüsselten (oder entschlüsselten) Binär-String zurück. Die Länge entspricht exakt der Länge von message. Im Fehlerfall wird eine SodiumException geworfen.

Beispiele

Einfache Ver- und Entschlüsselung mit initialem Zähler 0

<?php
$key   = sodium_crypto_stream_xchacha20_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES);

$message    = 'Geheime Nachricht';
$ciphertext = sodium_crypto_stream_xchacha20_xor_ic($message, $nonce, 0, $key);

// Entschlüsseln: gleicher Aufruf mit identischen Parametern
$decrypted = sodium_crypto_stream_xchacha20_xor_ic($ciphertext, $nonce, 0, $key);

echo $decrypted; // Geheime Nachricht
Geheime Nachricht

Segmentierte Verschlüsselung einer großen Datei mit Block-Offset

<?php
// Schlüssel und Nonce einmalig erzeugen und sicher speichern
$key   = sodium_crypto_stream_xchacha20_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES);

$blockSize = 64; // XChaCha20 arbeitet intern mit 64-Byte-Blöcken
$data      = str_repeat('A', 256); // 256 Byte Dummy-Daten

// Segmente einzeln verschlüsseln; jedes Segment beginnt am richtigen Offset
$ciphertextParts = [];
for ($i = 0; $i < 4; $i++) {
    $segment              = substr($data, $i * $blockSize, $blockSize);
    $ciphertextParts[$i]  = sodium_crypto_stream_xchacha20_xor_ic(
        $segment,
        $nonce,
        $i,  // Block-Zähler entspricht dem Segment-Index
        $key
    );
}

$fullCiphertext = implode('', $ciphertextParts);

// Gesamten Chiffretext auf einmal entschlüsseln (zum Vergleich)
$decryptedFull = sodium_crypto_stream_xchacha20_xor_ic($fullCiphertext, $nonce, 0, $key);

echo ($decryptedFull === $data) ? 'Daten korrekt rekonstruiert' : 'Fehler!';
Daten korrekt rekonstruiert

// Wichtig · Fallstricke

Keine Authentifizierung: Diese Funktion schützt ausschließlich die Vertraulichkeit. Angreifer können den Chiffretext unbemerkt manipulieren (Bit-Flipping-Angriffe). Für die meisten Anwendungsfälle ist sodium_crypto_aead_xchacha20poly1305_ietf_encrypt die deutlich sicherere Wahl.

Nonce-Wiederverwendung ist fatal: Wird dieselbe (Nonce, Schlüssel)-Kombination für zwei verschiedene Nachrichten genutzt, kann ein Angreifer durch XOR beider Chiffretexte den Klartext beider Nachrichten rekonstruieren.

Verfügbarkeit: Die Funktion erfordert libsodium ≥ 1.0.18 und ist in PHP ab Version 8.1 standardmäßig enthalten. In älteren PHP-Versionen steht sie über die sodium-Extension ggf. nicht zur Verfügung.