Start · Sprachen · PHP · Referenz · sodium_crypto_secretbox

sodium_crypto_secretbox

Funktion

Verschlüsselt und authentifiziert eine Nachricht mit einem gemeinsamen symmetrischen Schlüssel (XSalsa20-Poly1305).

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_secretbox(string $message, string $nonce, string $key): string

Beschreibung

sodium_crypto_secretbox() implementiert authentifizierte Verschlüsselung auf Basis von XSalsa20 (Stromchiffre) kombiniert mit Poly1305 (MAC). Das bedeutet: Die Funktion stellt sowohl die Vertraulichkeit (niemand kann den Klartext lesen) als auch die Integrität und Authentizität (niemand kann den Geheimtext unbemerkt verändern) der Nachricht sicher.

Das Verfahren ist ein klassisches Secret-Key-Szenario: Sender und Empfänger teilen sich einen gemeinsamen geheimen Schlüssel. Der Schlüssel muss geheim und zufällig sein; er sollte mit sodium_crypto_secretbox_keygen() erzeugt werden. Der Nonce (Number used once) muss für jede Verschlüsselungsoperation mit demselben Schlüssel einmalig sein, muss aber nicht geheim gehalten werden. Er kann beispielsweise zusammen mit dem Geheimtext übertragen werden.

Zum Entschlüsseln wird sodium_crypto_secretbox_open() verwendet. Schlägt die Authentifizierungsprüfung fehl (d.h. der Geheimtext wurde manipuliert oder ein falscher Schlüssel/Nonce verwendet), gibt diese Funktion false zurück — es wird kein Klartext preisgegeben.

Typische Einsatzgebiete sind die Verschlüsselung von Daten, die lokal gespeichert werden (z.B. in einer Datenbank oder einer Datei), sowie die symmetrische Kommunikation zwischen zwei Parteien, die denselben Schlüssel sicher ausgetauscht haben.

Parameter

Name Typ Default Beschreibung
$message Pflicht string Die zu verschlüsselnde Klartextnachricht als Binär-String beliebiger Länge.
$nonce Pflicht string Ein einmaliger Zufallswert (Number used once) der Länge SODIUM_CRYPTO_SECRETBOX_NONCEBYTES (24 Byte). Muss pro Schlüssel nur einmalig sein, kann aber öffentlich übertragen werden. Erzeugen mit random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES).
$key Pflicht string Der geheime symmetrische Schlüssel der Länge SODIUM_CRYPTO_SECRETBOX_KEYBYTES (32 Byte). Sollte mit sodium_crypto_secretbox_keygen() erzeugt werden.

Rückgabewert

Typ
string
Beschreibung
Gibt den verschlüsselten und authentifizierten Geheimtext als Binär-String zurück. Der Rückgabewert ist SODIUM_CRYPTO_SECRETBOX_MACBYTES (16 Byte) länger als die Eingabenachricht, da der Poly1305-MAC vorangestellt wird. Bei einem Fehler (z.B. ungültige Parameterlängen) wird eine SodiumException geworfen.

Beispiele

Nachricht verschlüsseln und wieder entschlüsseln

<?php
// Schlüssel und Nonce erzeugen
$key   = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

$klartext  = 'Geheime Nachricht: Passwort ist 1234';
$geheimtext = sodium_crypto_secretbox($klartext, $nonce, $key);

echo 'Geheimtext (Base64): ' . base64_encode($geheimtext) . PHP_EOL;

// Entschlüsseln
$entschluesselt = sodium_crypto_secretbox_open($geheimtext, $nonce, $key);

if ($entschluesselt === false) {
    throw new RuntimeException('Entschlüsselung fehlgeschlagen: Nachricht manipuliert?');
}

echo 'Klartext: ' . $entschluesselt . PHP_EOL;

// Speicher für sensitive Daten bereinigen
sodium_memzero($key);
Geheimtext (Base64): <base64-kodierter Wert> Klartext: Geheime Nachricht: Passwort ist 1234

Verschlüsselten Wert in der Datenbank speichern

<?php
// Schlüssel aus sicherer Konfiguration laden (z.B. Umgebungsvariable)
$key = sodium_hex2bin(getenv('APP_SECRET_KEY'));

function verschluesseln(string $wert, string $key): string {
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    $geheimtext = sodium_crypto_secretbox($wert, $nonce, $key);
    // Nonce + Geheimtext kombiniert speichern
    return base64_encode($nonce . $geheimtext);
}

function entschluesseln(string $gespeicherterWert, string $key): string|false {
    $decoded    = base64_decode($gespeicherterWert);
    $nonce      = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
    $geheimtext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
    return sodium_crypto_secretbox_open($geheimtext, $nonce, $key);
}

$iban = 'DE89370400440532013000';
$gespeichert = verschluesseln($iban, $key);
echo 'In DB gespeichert: ' . $gespeichert . PHP_EOL;

$wiederhergestellt = entschluesseln($gespeichert, $key);
echo 'Wiederhergestellt: ' . $wiederhergestellt . PHP_EOL;
In DB gespeichert: <base64-kodierter Wert> Wiederhergestellt: DE89370400440532013000

// Wichtig · Fallstricke

Nonce-Wiederverwendung ist fatal: Wird derselbe Nonce mit demselben Schlüssel für zwei verschiedene Nachrichten verwendet, kann ein Angreifer den Klartext beider Nachrichten rekonstruieren. Verwende immer random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES) für einen frischen, kryptografisch sicheren Nonce.

Schlüsselverwaltung: Der geheime Schlüssel darf niemals im Quellcode stehen. Verwende Umgebungsvariablen, einen Secret-Manager oder ein Hardware Security Module (HSM). Nach Verwendung im Speicher sollte er mit sodium_memzero() überschrieben werden.

Kein Public-Key-Verfahren: Diese Funktion ist für Szenarien mit einem gemeinsamen geheimen Schlüssel gedacht. Für die Kommunikation zwischen zwei Parteien ohne vorherigen sicheren Schlüsselaustausch sollte stattdessen sodium_crypto_box() (Public-Key-Verschlüsselung) verwendet werden.

Fehlerbehandlung: Die Funktion wirft bei ungültigen Parameterlängen eine SodiumException. Stelle sicher, dass Schlüssel und Nonce die korrekten Längen haben (SODIUM_CRYPTO_SECRETBOX_KEYBYTES bzw. SODIUM_CRYPTO_SECRETBOX_NONCEBYTES).