Start · Sprachen · PHP · Referenz · sodium_crypto_secretstream_xchacha20poly1305_pull

sodium_crypto_secretstream_xchacha20poly1305_pull

Funktion

Entschlüsselt einen einzelnen Datenblock aus einem mit XChaCha20-Poly1305 verschlüsselten Stream und gibt Klartext sowie Tag zurück.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_secretstream_xchacha20poly1305_pull(string &$state, string $ciphertext, string|null $additional_data = null): array|false

Beschreibung

sodium_crypto_secretstream_xchacha20poly1305_pull ist der Gegenspieler zu sodium_crypto_secretstream_xchacha20poly1305_push: Sie entschlüsselt einen zuvor verschlüsselten Block (Ciphertext) aus einem symmetrischen Stream und überprüft dabei gleichzeitig die Authentizität des Blocks mittels Poly1305-MAC. Der interne Stream-Zustand wird dabei automatisch fortgeschrieben, sodass jeder Block sequenziell verarbeitet werden muss.

Der Rückgabewert ist ein Array mit zwei Einträgen: dem entschlüsselten Klartext ([0]) und dem Tag ([1]). Das Tag ermöglicht es, besondere Block-Typen zu erkennen – etwa das Ende eines Streams (SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL) oder einen Neustart der Nonce-Ableitung (TAG_REKEY).

Optionale Additional Data ($additional_data) werden in die MAC-Berechnung einbezogen, aber nicht verschlüsselt. Sender und Empfänger müssen identische Additional Data verwenden, sonst schlägt die Authentifizierung fehl und die Funktion gibt false zurück. Dies eignet sich z. B. zum Einbinden von Metadaten wie Sequenznummern oder Zeitstempeln.

Typische Einsatzgebiete sind das Entschlüsseln großer Dateien in Chunks, verschlüsselte Netzwerk-Streams oder jede Situation, in der Daten in mehreren aufeinanderfolgenden Blöcken übertragen werden und Manipulationsschutz benötigt wird.

Parameter

Name Typ Default Beschreibung
$state Pflicht string Der Stream-Zustand (per Referenz übergeben), der zuvor mit sodium_crypto_secretstream_xchacha20poly1305_init_pull erzeugt wurde. Er wird durch jeden Aufruf automatisch weiterentwickelt.
$ciphertext Pflicht string Der verschlüsselte Datenblock, wie ihn sodium_crypto_secretstream_xchacha20poly1305_push erzeugt hat. Enthält sowohl den Chiffrat-Text als auch den Authentication Tag.
$additional_data string|null null Optionale, nicht verschlüsselte Zusatzdaten, die bei der Authentifizierung berücksichtigt werden. Müssen exakt mit den beim Verschlüsseln verwendeten Additional Data übereinstimmen, sonst schlägt die Verifikation fehl.

Rückgabewert

Typ
array|false
Beschreibung
Bei Erfolg ein Array mit zwei Elementen: [0] enthält den entschlüsselten Klartext als string, [1] enthält das Tag als int (z. B. SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE oder TAG_FINAL). Gibt false zurück, wenn die Authentifizierung fehlschlägt oder der Ciphertext manipuliert wurde.

Beispiele

Vollständiges Verschlüsseln und Entschlüsseln eines Streams

<?php
// Schlüssel generieren
$key = sodium_crypto_secretstream_xchacha20poly1305_keygen();

// === Sender: Verschlüsseln ===
[$header, $pushState] = 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($pushState, $chunk, null, $tag);
}

// === Empfänger: Entschlüsseln ===
$pullState = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key);

foreach ($ciphertexts as $ct) {
    $result = sodium_crypto_secretstream_xchacha20poly1305_pull($pullState, $ct);
    if ($result === false) {
        echo "Authentifizierung fehlgeschlagen!\n";
        break;
    }
    [$plaintext, $tag] = $result;
    echo $plaintext;
    if ($tag === SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL) {
        echo "\n[Stream beendet]\n";
    }
}
Hallo, Welt! [Stream beendet]

Entschlüsseln mit Additional Data (Authentifizierung von Metadaten)

<?php
$key = sodium_crypto_secretstream_xchacha20poly1305_keygen();

// Verschlüsseln mit Additional Data
[$header, $pushState] = sodium_crypto_secretstream_xchacha20poly1305_init_push($key);
$metadata = 'seq:42|user:alice';
$ct = sodium_crypto_secretstream_xchacha20poly1305_push(
    $pushState,
    'Geheime Nachricht',
    $metadata,
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL
);

// Entschlüsseln mit korrekten Additional Data
$pullState = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key);
$result = sodium_crypto_secretstream_xchacha20poly1305_pull($pullState, $ct, $metadata);
if ($result !== false) {
    echo 'Klartext: ' . $result[0] . PHP_EOL;
} else {
    echo 'Verifikation fehlgeschlagen!' . PHP_EOL;
}

// Entschlüsseln mit FALSCHEN Additional Data → false
$pullState2 = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key);
$result2 = sodium_crypto_secretstream_xchacha20poly1305_pull($pullState2, $ct, 'seq:99|user:eve');
var_dump($result2); // bool(false)
Klartext: Geheime Nachricht bool(false)

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Der Rückgabewert false bedeutet eine fehlgeschlagene Authentifizierung – der Ciphertext wurde entweder manipuliert, der Schlüssel ist falsch oder die Blöcke wurden in falscher Reihenfolge verarbeitet. In diesem Fall darf der (teilweise) Klartext unter keinen Umständen verwendet werden.
  • Der Stream-Zustand muss immer streng sequenziell verwendet werden. Blöcke dürfen weder vertauscht noch übersprungen werden.
  • Prüfe nach dem letzten Block explizit auf SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL, um sicherzustellen, dass kein Angreifer einen abgeschnittenen Stream liefert (Truncation Attack).
  • Der Schlüssel sollte mit sodium_crypto_secretstream_xchacha20poly1305_keygen erzeugt und sicher gespeichert werden (z. B. über Umgebungsvariablen, nie im Quellcode).
  • Beachte, dass sodium_memzero verwendet werden sollte, um den Schlüssel nach Gebrauch sicher aus dem Speicher zu löschen.