Start · Sprachen · PHP · Referenz · sodium_crypto_secretstream_xchacha20poly1305_init_pull

sodium_crypto_secretstream_xchacha20poly1305_init_pull

Funktion

Initialisiert einen Secretstream-Kontext zum Entschlüsseln von Nachrichten, die mit <code>xchacha20poly1305</code> verschlüsselt wurden.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_secretstream_xchacha20poly1305_init_pull(string $header, string $key): resource|object

Beschreibung

Diese Funktion bereitet einen Entschlüsselungskontext für die Libsodium-Secretstream-API vor. Sie wird auf der Empfängerseite eingesetzt und bildet das Gegenstück zur Push-Initialisierung (sodium_crypto_secretstream_xchacha20poly1305_init_push). Der zurückgegebene Kontext wird anschließend wiederholt mit sodium_crypto_secretstream_xchacha20poly1305_pull verwendet, um einzelne Nachrichten aus dem verschlüsselten Datenstrom zu entschlüsseln und zu authentifizieren.

Die Secretstream-API eignet sich besonders für die sichere Übertragung von Datenströmen (z. B. Dateien, Netzwerkstreams), bei denen mehrere Nachrichten nacheinander mit demselben Schlüssel verschlüsselt werden, jede Nachricht jedoch einzeln entschlüsselt und verifiziert werden kann. Sie schützt vor Wiedereinspielen, Umordnen und Manipulation einzelner Nachrichten.

Der $header-Wert enthält den zufälligen Nonce, der vom Sender beim Initialisieren des Push-Kontexts erzeugt wurde. Er muss daher zusammen mit den verschlüsselten Nachrichten übertragen werden, ist aber selbst kein Geheimnis. Der $key hingegen muss geheim gehalten und über einen sicheren Kanal ausgetauscht werden (z. B. via sodium_crypto_kx).

Der Kontext ist zustandsbehaftet: Er muss für den gesamten Entschlüsselungsvorgang eines Streams erhalten bleiben und darf nicht wiederverwendet werden. Nach einem Entschlüsselungsfehler ist der Kontext ungültig und soll verworfen werden.

Parameter

Name Typ Default Beschreibung
$header Pflicht string Der vom Sender erzeugte Header (Nonce), der bei sodium_crypto_secretstream_xchacha20poly1305_init_push zurückgegeben wurde. Seine Länge muss exakt SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES Bytes betragen.
$key Pflicht string Der geheime symmetrische Schlüssel zum Entschlüsseln. Muss exakt SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES Bytes lang sein und identisch mit dem beim Sender verwendeten Schlüssel sein.

Rückgabewert

Typ
resource|object
Beschreibung
Gibt einen Secretstream-Pull-Kontext zurück, der als Zustandsobjekt für nachfolgende Aufrufe von sodium_crypto_secretstream_xchacha20poly1305_pull dient. Im Fehlerfall wird eine SodiumException geworfen.

Beispiele

Einfacher Datenstrom entschlüsseln

<?php
// Schlüssel und Header vom Sender empfangen (Header ist KEIN Geheimnis)
$key    = sodium_hex2bin('...'); // 32-Byte-Schlüssel, sicher übertragen
$header = sodium_hex2bin('...'); // Header aus dem verschlüsselten Datenstrom

// Empfangene verschlüsselte Nachrichten (inkl. Tag)
$ciphertexts = [
    // ... binäre Ciphertext-Blöcke vom Sender
];

// Entschlüsselungskontext initialisieren
$state = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key);

foreach ($ciphertexts as $ciphertext) {
    [$plaintext, $tag] = sodium_crypto_secretstream_xchacha20poly1305_pull($state, $ciphertext);

    if ($plaintext === false) {
        throw new RuntimeException('Entschlüsselung fehlgeschlagen – Nachricht manipuliert oder Kontext ungültig.');
    }

    echo $plaintext . PHP_EOL;

    if ($tag === SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL) {
        echo 'Stream vollständig empfangen.' . PHP_EOL;
        break;
    }
}

sodium_memzero($key);

Vollständiger Encrypt-Decrypt-Roundtrip

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

// === Sender-Seite ===
[$state_push, $header] = sodium_crypto_secretstream_xchacha20poly1305_init_push($key);

$c1 = sodium_crypto_secretstream_xchacha20poly1305_push(
    $state_push,
    'Erste Nachricht',
    '',
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE
);
$c2 = sodium_crypto_secretstream_xchacha20poly1305_push(
    $state_push,
    'Letzte Nachricht',
    '',
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL
);

// $header und $c1, $c2 an Empfänger übertragen

// === Empfänger-Seite ===
$state_pull = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key);

[$msg1, $tag1] = sodium_crypto_secretstream_xchacha20poly1305_pull($state_pull, $c1);
[$msg2, $tag2] = sodium_crypto_secretstream_xchacha20poly1305_pull($state_pull, $c2);

echo $msg1 . PHP_EOL; // Erste Nachricht
echo $msg2 . PHP_EOL; // Letzte Nachricht
echo ($tag2 === SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL ? 'FINAL' : '') . PHP_EOL;

sodium_memzero($key);
Erste Nachricht Letzte Nachricht FINAL

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Der $key darf niemals im Klartext über unsichere Kanäle übertragen werden. Verwende z. B. sodium_crypto_kx oder sodium_crypto_box für den Schlüsselaustausch.
  • Der $header ist kein Geheimnis, muss aber vollständig und unverändert übertragen werden. Eine Manipulation des Headers führt zur fehlgeschlagenen Entschlüsselung.
  • Bei einem fehlgeschlagenen pull-Aufruf (Rückgabe false) ist der gesamte Kontext kompromittiert und muss verworfen werden. Es dürfen keine weiteren Nachrichten verarbeitet werden.
  • Schlüssel sollten nach Verwendung mit sodium_memzero aus dem Speicher gelöscht werden, um Side-Channel-Angriffe zu erschweren.
  • Die Secretstream-API bietet keine Schutz gegen Replay-Angriffe auf Stream-Ebene (d. h. das Wiederverwenden eines kompletten Streams mit demselben Header und Schlüssel). Schlüssel sollten daher pro Session einmalig sein.