Start · Sprachen · PHP · Referenz · sodium_crypto_secretstream_xchacha20poly1305_rekey

sodium_crypto_secretstream_xchacha20poly1305_rekey

Funktion

Rotiert explizit den internen Schlüssel eines XChaCha20-Poly1305-Secretstream-Status-Objekts, ohne dabei eine Nachricht zu senden.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_secretstream_xchacha20poly1305_rekey(string &$state): void

Beschreibung

Die Funktion sodium_crypto_secretstream_xchacha20poly1305_rekey führt eine manuelle Schlüsselrotation (Rekey) im laufenden Secretstream-Zustand durch. Dabei wird der interne Subkey des Streams kryptografisch neu abgeleitet, ohne dass eine verschlüsselte Nachricht an den Empfänger übermittelt wird.

Normalerweise rotiert der Secretstream-Mechanismus den Schlüssel automatisch bei Verwendung des Tags SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY. Die explizite Rekey-Funktion ermöglicht hingegen eine einseitige, unangekündigte Rotation – zum Beispiel wenn der Sender den Zustand nach einem bestimmten Zeitpunkt oder einer bestimmten Datenmenge unlesbar machen möchte, selbst wenn ein Angreifer Teile des Zustands zuvor mitgelesen hat.

Dies ist besonders nützlich für langlebige Streams oder sicherheitskritische Protokolle, bei denen Forward Secrecy auf Chunk-Ebene gewünscht wird: Bereits verschlüsselte Chunks können nach einem Rekey nicht mehr mit dem neuen Schlüsselzustand entschlüsselt werden. Der entsprechende Empfänger-Zustand muss synchron (via Tag oder Protokollabsprache) ebenfalls rekeyed werden.

Der Parameter $state wird als Referenz übergeben und direkt modifiziert. Die Funktion gibt keinen Wert zurück.

Parameter

Name Typ Default Beschreibung
$state Pflicht string Der aktuelle Secretstream-Zustand (als binärer String), der von sodium_crypto_secretstream_xchacha20poly1305_init_push oder sodium_crypto_secretstream_xchacha20poly1305_init_pull erzeugt wurde. Wird als Referenz übergeben und direkt verändert.

Rückgabewert

Typ
void
Beschreibung
Gibt keinen Wert zurück. Der übergebene Zustand wird direkt (in-place) modifiziert.

Beispiele

Explizites Rekey auf der Sender-Seite

<?php
// Schlüssel und Header erzeugen
$key = sodium_crypto_secretstream_xchacha20poly1305_keygen();
[$state_push, $header] = sodium_crypto_secretstream_xchacha20poly1305_init_push($key);

// Erste Nachricht verschlüsseln
$chunk1 = sodium_crypto_secretstream_xchacha20poly1305_push(
    $state_push,
    'Nachricht 1',
    '',
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE
);

// Explizites Rekey — Zustand wird neu abgeleitet
sodium_crypto_secretstream_xchacha20poly1305_rekey($state_push);

// Zweite Nachricht verschlüsseln (mit neuem Subkey)
$chunk2 = sodium_crypto_secretstream_xchacha20poly1305_push(
    $state_push,
    'Nachricht 2',
    '',
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL
);

echo 'Chunk 1 Länge: ' . strlen($chunk1) . PHP_EOL;
echo 'Chunk 2 Länge: ' . strlen($chunk2) . PHP_EOL;
Chunk 1 Länge: 27 Chunk 2 Länge: 27

Synchrones Rekey auf Sender- und Empfänger-Seite

<?php
$key = sodium_crypto_secretstream_xchacha20poly1305_keygen();
[$state_push, $header] = sodium_crypto_secretstream_xchacha20poly1305_init_push($key);
$state_pull = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key);

// Nachricht senden
$encrypted = sodium_crypto_secretstream_xchacha20poly1305_push(
    $state_push,
    'Geheimtext vor Rekey',
    '',
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE
);

// Empfänger empfängt die Nachricht
[$decrypted, $tag] = sodium_crypto_secretstream_xchacha20poly1305_pull($state_pull, $encrypted);
echo 'Empfangen: ' . $decrypted . PHP_EOL;

// Beide Seiten führen manuell Rekey durch (z. B. nach Protokollabsprache)
sodium_crypto_secretstream_xchacha20poly1305_rekey($state_push);
sodium_crypto_secretstream_xchacha20poly1305_rekey($state_pull);

// Kommunikation nach Rekey
$encrypted2 = sodium_crypto_secretstream_xchacha20poly1305_push(
    $state_push,
    'Geheimtext nach Rekey',
    '',
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL
);
[$decrypted2, $tag2] = sodium_crypto_secretstream_xchacha20poly1305_pull($state_pull, $encrypted2);
echo 'Empfangen nach Rekey: ' . $decrypted2 . PHP_EOL;
Empfangen: Geheimtext vor Rekey Empfangen nach Rekey: Geheimtext nach Rekey

// Wichtig · Fallstricke

Synchronisierung erforderlich: Wenn sodium_crypto_secretstream_xchacha20poly1305_rekey auf der Sender-Seite aufgerufen wird, muss dasselbe Rekey exakt zur gleichen Stelle im Stream auch auf der Empfänger-Seite durchgeführt werden – andernfalls schlägt die Entschlüsselung aller nachfolgenden Nachrichten fehl. Das Rekey wird nicht automatisch im verschlüsselten Datenstrom signalisiert.

Unterschied zu Tag-Rekey: Das Tag SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY teilt dem Empfänger innerhalb des Streams mit, dass ein Rekey stattgefunden hat. Die vorliegende Funktion hingegen rekeyed den Zustand still, ohne dass eine Nachricht verschickt wird – die Synchronisierung liegt vollständig beim Protokoll-Entwickler.

Forward Secrecy: Nach dem Rekey ist es (für einen Angreifer, der den alten Zustand kannte) nicht mehr möglich, zukünftige Nachrichten zu entschlüsseln. Gleichzeitig können bereits empfangene Chunks mit dem neuen Zustand nicht mehr verifiziert oder neu entschlüsselt werden.