Start · Sprachen · PHP · Referenz · sodium_crypto_secretstream_xchacha20poly1305_push

sodium_crypto_secretstream_xchacha20poly1305_push

Funktion

Verschlüsselt einen Datenblock im Kontext einer XChaCha20-Poly1305-Streaming-Sitzung und hängt ihn an den verschlüsselten Datenstrom an.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_secretstream_xchacha20poly1305_push(string &$state, string $msg, string $ad = '', int $tag = SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE): string

Beschreibung

sodium_crypto_secretstream_xchacha20poly1305_push() gehört zur libsodium-Streaming-Verschlüsselungs-API und verschlüsselt einzelne Nachrichten-Chunks innerhalb einer zuvor initialisierten Sitzung. Der Zustand $state wird dabei fortlaufend aktualisiert, sodass jeder Chunk kryptographisch an den vorherigen gebunden ist – das verhindert das Umsortieren oder Entfernen einzelner Blöcke.

Die Funktion eignet sich besonders für große Dateien oder Datenströme, die nicht vollständig im Speicher gehalten werden können. Statt die gesamte Datei auf einmal zu verschlüsseln, wird sie in überschaubare Chunks aufgeteilt, die nacheinander verarbeitet werden. Der Empfänger entschlüsselt die Chunks in derselben Reihenfolge mit sodium_crypto_secretstream_xchacha20poly1305_pull().

Über den optionalen Parameter $ad (Additional Data) können nicht-verschlüsselte, aber authentifizierte Metadaten mitgegeben werden – z. B. Dateinamen oder Sequenznummern. Der $tag-Parameter steuert besondere Semantik einzelner Chunks, etwa um das Ende des Streams (SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL) zu signalisieren.

Wichtig: Der initiale $state muss zuvor mit sodium_crypto_secretstream_xchacha20poly1305_init_push() erzeugt werden. Der dabei generierte Header muss dem Empfänger mitgeteilt werden, damit dieser den Zustand für die Entschlüsselung korrekt initialisieren kann.

Parameter

Name Typ Default Beschreibung
$state Pflicht string Referenz auf den internen Sitzungszustand, der zuvor mit sodium_crypto_secretstream_xchacha20poly1305_init_push() erzeugt wurde. Wird bei jedem Aufruf in-place aktualisiert.
$msg Pflicht string Der Klartext-Datenblock (Chunk), der verschlüsselt werden soll. Die Länge kann variieren, sollte jedoch für optimale Performance und Sicherheit konsistent gehalten werden.
$ad string '' Optionale zusätzliche Daten (Additional Data), die nicht verschlüsselt, aber in die Authentifizierung einbezogen werden. Wird beim Entschlüsseln auf Integrität geprüft.
$tag int SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE Steuert die Bedeutung des Chunks. Mögliche Werte: SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE (normaler Block), SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH (Senderseite leert interne Puffer), SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY (erzwingt internen Schlüsselwechsel), SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL (letzter Block des Streams).

Rückgabewert

Typ
string
Beschreibung
Gibt den verschlüsselten und authentifizierten Ciphertext-Chunk als binären String zurück. Der Rückgabewert ist um SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES Bytes länger als der eingegebene Klartext (für den Authentifizierungs-Tag).

Beispiele

Große Datei chunkweise verschlüsseln

<?php
// Schlüssel erzeugen (sicher aufbewahren!)
$key = sodium_crypto_secretstream_xchacha20poly1305_keygen();

// Verschlüsselungs-Sitzung initialisieren
['state' => $state, 'header' => $header] =
    sodium_crypto_secretstream_xchacha20poly1305_init_push($key);

$inputFile  = '/pfad/zur/quelldatei.bin';
$outputFile = '/pfad/zur/zieldatei.enc';
$chunkSize  = 4096; // 4 KB pro Chunk

$in  = fopen($inputFile,  'rb');
$out = fopen($outputFile, 'wb');

// Header voranstellen, damit der Empfänger den Zustand rekonstruieren kann
fwrite($out, $header);

while (!feof($in)) {
    $plaintext = fread($in, $chunkSize);
    $isLast    = feof($in);
    $tag       = $isLast
        ? SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL
        : SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE;

    $cipherChunk = sodium_crypto_secretstream_xchacha20poly1305_push(
        $state,
        $plaintext,
        '',    // keine Additional Data
        $tag
    );
    fwrite($out, $cipherChunk);
}

fclose($in);
fclose($out);
sodium_memzero($key);

echo "Datei erfolgreich verschlüsselt.\n";
Datei erfolgreich verschlüsselt.

Chunks mit Additional Data verschlüsseln und entschlüsseln

<?php
$key = sodium_crypto_secretstream_xchacha20poly1305_keygen();

// --- Verschlüsseln ---
['state' => $encState, 'header' => $header] =
    sodium_crypto_secretstream_xchacha20poly1305_init_push($key);

$chunks = ['Hallo', ' ', 'Welt'];
$ciphertexts = [];
foreach ($chunks as $i => $chunk) {
    $isLast = ($i === array_key_last($chunks));
    $tag    = $isLast
        ? SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL
        : SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE;

    $ciphertexts[] = sodium_crypto_secretstream_xchacha20poly1305_push(
        $encState,
        $chunk,
        'seq=' . $i, // authentifizierte Sequenznummer
        $tag
    );
}

// --- Entschlüsseln ---
$decState = sodium_crypto_secretstream_xchacha20poly1305_init_pull(
    $header,
    $key
);

$result = '';
foreach ($ciphertexts as $i => $cipher) {
    [$plain, $tag] = sodium_crypto_secretstream_xchacha20poly1305_pull(
        $decState,
        $cipher,
        'seq=' . $i // muss identisch zur Verschlüsselungs-AD sein
    );
    if ($plain === false) {
        throw new RuntimeException('Entschlüsselung fehlgeschlagen!');
    }
    $result .= $plain;
}

echo $result . "\n";
Hallo Welt

// Wichtig · Fallstricke

Schlüsselverwaltung: Der Schlüssel sollte ausschließlich über sodium_crypto_secretstream_xchacha20poly1305_keygen() erzeugt und nach Gebrauch mit sodium_memzero() aus dem Speicher gelöscht werden, um das Risiko von Speicher-Dumps zu minimieren.

Header übertragen: Der von init_push() zurückgegebene Header ist kein Geheimnis, muss aber unverändert an den Empfänger übermittelt werden – typischerweise als erste Bytes der verschlüsselten Datei oder des Streams.

Reihenfolge zwingend: Chunks dürfen beim Entschlüsseln nicht umgeordnet werden. Jeder fehlende oder veränderte Chunk führt zu einem Authentifizierungsfehler. Die Streaming-API erkennt solche Manipulationen zuverlässig.

TAG_FINAL: Der letzte Chunk muss mit SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL markiert werden. Fehlt dieses Tag, erkennt der Empfänger das vorzeitige Ende des Streams und schlägt die Authentifizierung fehl.