Signatur
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
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);
// Wichtig · Fallstricke
Sicherheitshinweise:
- Der
$keydarf niemals im Klartext über unsichere Kanäle übertragen werden. Verwende z. B.sodium_crypto_kxodersodium_crypto_boxfür den Schlüsselaustausch. - Der
$headerist 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ückgabefalse) ist der gesamte Kontext kompromittiert und muss verworfen werden. Es dürfen keine weiteren Nachrichten verarbeitet werden. - Schlüssel sollten nach Verwendung mit
sodium_memzeroaus 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.