Start · Sprachen · PHP · Referenz · sodium_crypto_aead_xchacha20poly1305_ietf_encrypt

sodium_crypto_aead_xchacha20poly1305_ietf_encrypt

Funktion

Verschlüsselt und authentifiziert eine Nachricht mittels XChaCha20-Poly1305 (IETF-Variante) und gibt den Geheimtext inkl. MAC-Tag zurück.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(string $message, string $additional_data, string $nonce, string $key): string

Beschreibung

XChaCha20-Poly1305 ist eine Authenticated Encryption with Associated Data (AEAD)-Verschlüsselung, die zwei kryptografische Primitive kombiniert: die Stromchiffre XChaCha20 für die eigentliche Verschlüsselung und den Message Authentication Code Poly1305 zur Integritätsprüfung. Das Ergebnis ist ein Geheimtext, der nur entschlüsselt werden kann, wenn Schlüssel, Nonce und optionale Zusatzdaten unverändert sind.

Im Vergleich zu sodium_crypto_aead_chacha20poly1305_ietf_encrypt verwendet XChaCha20 einen deutlich längeren Nonce (192 Bit statt 96 Bit). Das macht zufällig generierte Nonces (random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES)) praktisch kollisionssicher und eignet sich daher besonders gut für Anwendungen, in denen viele Nachrichten mit demselben Schlüssel verschlüsselt werden, ohne einen Nonce-Counter führen zu müssen.

Der Parameter $additional_data erlaubt es, beliebige unverschlüsselte Metadaten (z. B. Absender-ID, Zeitstempel) kryptografisch an den Geheimtext zu binden, ohne sie selbst zu verschlüsseln. Bei der Entschlüsselung müssen dieselben Zusatzdaten übergeben werden – sonst schlägt die Authentifizierung fehl. Werden keine Zusatzdaten benötigt, kann ein leerer String übergeben werden.

Die Funktion ist die empfohlene AEAD-Variante in libsodium, wenn keine spezifischen Kompatibilitätsanforderungen mit anderen Bibliotheken bestehen. Für die Entschlüsselung wird sodium_crypto_aead_xchacha20poly1305_ietf_decrypt verwendet.

Parameter

Name Typ Default Beschreibung
$message Pflicht string Der Klartext, der verschlüsselt und authentifiziert werden soll.
$additional_data Pflicht string Optionale, unverschlüsselte Zusatzdaten, die in den Authentifizierungs-Tag einfließen (z. B. Header oder Kontext-Informationen). Kann ein leerer String sein, muss aber angegeben werden.
$nonce Pflicht string Ein einmalig verwendeter Zufallswert (Number-used-once) der Länge SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES (24 Byte). Darf für denselben Schlüssel niemals zweimal verwendet werden.
$key Pflicht string Der geheime Schlüssel der Länge SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES (32 Byte). Sollte mit sodium_crypto_aead_xchacha20poly1305_ietf_keygen() erzeugt werden.

Rückgabewert

Typ
string
Beschreibung
Der verschlüsselte Geheimtext als binärer String. Er enthält sowohl den eigentlichen Chiffretext als auch den 16-Byte-Poly1305-Authentifizierungs-Tag (angehängt). Die Länge beträgt strlen($message) + SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES.

Beispiele

Einfaches Verschlüsseln und Entschlüsseln einer Nachricht

<?php
// Schlüssel und Nonce generieren
$key   = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);

$plaintext       = 'Geheime Nachricht: Hello, World!';
$additional_data = ''; // keine Zusatzdaten

// Verschlüsseln
$ciphertext = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
    $plaintext,
    $additional_data,
    $nonce,
    $key
);

echo 'Geheimtext (hex): ' . bin2hex($ciphertext) . PHP_EOL;

// Entschlüsseln
$decrypted = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
    $ciphertext,
    $additional_data,
    $nonce,
    $key
);

if ($decrypted === false) {
    throw new RuntimeException('Entschlüsselung fehlgeschlagen – Daten manipuliert?');
}

echo 'Klartext: ' . $decrypted . PHP_EOL;

// Speicher bereinigen
sodium_memzero($key);
Geheimtext (hex): <hexadezimaler Zufallsstring> Klartext: Geheime Nachricht: Hello, World!

Verschlüsselung mit Additional Data (z. B. Benutzer-ID binden)

<?php
$key   = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);

$userId          = 'user-42';
$additional_data = $userId; // Benutzer-ID als Kontext-Bindung
$payload         = json_encode(['role' => 'admin', 'exp' => time() + 3600]);

// Verschlüsseln – Payload ist an $userId gebunden
$ciphertext = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
    $payload,
    $additional_data,
    $nonce,
    $key
);

// Sicher übertragen: Nonce + Geheimtext (base64-kodiert)
$transmitted = base64_encode($nonce . $ciphertext);
echo 'Übertragen: ' . $transmitted . PHP_EOL;

// Empfänger-Seite: Nonce extrahieren und entschlüsseln
$raw   = base64_decode($transmitted);
$nonce = substr($raw, 0, SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
$ct    = substr($raw, SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);

// Entschlüsselung schlägt fehl, wenn $additional_data nicht übereinstimmt
$result = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($ct, $userId, $nonce, $key);

if ($result === false) {
    echo 'Authentifizierung fehlgeschlagen!' . PHP_EOL;
} else {
    echo 'Entschlüsselt: ' . $result . PHP_EOL;
}

sodium_memzero($key);
Übertragen: <base64-String> Entschlüsselt: {"role":"admin","exp":<Zeitstempel>}

// Wichtig · Fallstricke

Nonce-Wiederverwendung ist fatal: Die Verwendung derselben Nonce mit demselben Schlüssel für zwei verschiedene Nachrichten bricht die Sicherheit des gesamten Schemas. Bei zufälligen 24-Byte-Nonces ist das Kollisionsrisiko vernachlässigbar, aber bei einem Counter-basierten Ansatz muss streng auf Eindeutigkeit geachtet werden.

Schlüsselverwaltung: Der Schlüssel sollte niemals im Klartext gespeichert werden. Verwende sodium_memzero() nach der Nutzung, um den Schlüssel aus dem Speicher zu löschen.

Nonce muss übertragen werden: Die Nonce ist kein Geheimnis und kann zusammen mit dem Geheimtext übertragen werden (typischerweise vorangestellt), muss aber für jede Verschlüsselung einzigartig sein.

Additional Data muss beidseitig bekannt sein: Wer den Geheimtext entschlüsselt, muss exakt dieselben Zusatzdaten kennen. Stimmen sie nicht überein, liefert sodium_crypto_aead_xchacha20poly1305_ietf_decrypt false zurück – ohne Information darüber, was falsch war (kein Timing-Leak).