Signatur
Beschreibung
Diese Funktion implementiert den clientseitigen Teil eines Diffie-Hellman-Schlüsselaustauschs (KX = Key Exchange) basierend auf der X25519-Kurve. Sie erzeugt aus dem eigenen Schlüsselpaar des Clients und dem öffentlichen Schlüssel des Servers zwei symmetrische Sitzungsschlüssel: einen zum Empfangen (rx) und einen zum Senden (tx).
Das resultierende Array enthält unter dem Schlüssel 'rx' den Schlüssel, mit dem der Client eingehende Nachrichten vom Server entschlüsselt, und unter 'tx' den Schlüssel, mit dem er Nachrichten an den Server verschlüsselt. Auf der Serverseite entspricht das tx des Clients dem rx des Servers und umgekehrt.
Das clientseitige Schlüsselpaar wird mit sodium_crypto_kx_keypair() oder sodium_crypto_kx_seed_keypair() generiert. Der öffentliche Schlüssel des Servers wird mit sodium_crypto_kx_publickey() aus dessen Schlüsselpaar extrahiert. Die so gewonnenen Sitzungsschlüssel können anschließend z. B. mit sodium_crypto_secretstream_xchacha20poly1305-Funktionen genutzt werden.
Der Schlüsselaustausch ist nicht-interaktiv, d. h. beide Seiten können die Sitzungsschlüssel unabhängig voneinander berechnen, sofern sie den jeweiligen öffentlichen Schlüssel der Gegenseite kennen. Dies macht das Verfahren besonders praktisch für sichere Kanal-Initialisierungen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $client_keypair Pflicht | string | Das vollständige Schlüsselpaar des Clients (privater + öffentlicher Schlüssel), erzeugt mit sodium_crypto_kx_keypair() oder sodium_crypto_kx_seed_keypair(). Die Länge beträgt SODIUM_CRYPTO_KX_KEYPAIRBYTES Bytes. |
|
| $server_public_key Pflicht | string | Der öffentliche Schlüssel des Servers mit einer Länge von SODIUM_CRYPTO_KX_PUBLICKEYBYTES Bytes, extrahiert z. B. mit sodium_crypto_kx_publickey(). |
Rückgabewert
'rx' enthält den Empfangsschlüssel (zum Entschlüsseln von Nachrichten des Servers) und 'tx' den Sendeschlüssel (zum Verschlüsseln von Nachrichten an den Server). Beide Schlüssel haben die Länge SODIUM_CRYPTO_KX_SESSIONKEYBYTES Bytes. Bei ungültigen Parametern wird eine SodiumException geworfen.Beispiele
Vollständiger Schlüsselaustausch zwischen Client und Server
<?php
// Schlüsselpaare generieren (normalerweise einmalig und sicher speichern)
$clientKeypair = sodium_crypto_kx_keypair();
$serverKeypair = sodium_crypto_kx_keypair();
// Öffentliche Schlüssel extrahieren
$clientPublicKey = sodium_crypto_kx_publickey($clientKeypair);
$serverPublicKey = sodium_crypto_kx_publickey($serverKeypair);
// Clientseitige Sitzungsschlüssel berechnen
$clientSessionKeys = sodium_crypto_kx_client_session_keys($clientKeypair, $serverPublicKey);
// Serverseitige Sitzungsschlüssel berechnen
$serverSessionKeys = sodium_crypto_kx_server_session_keys($serverKeypair, $clientPublicKey);
// Überprüfung: Client-TX muss Server-RX entsprechen und umgekehrt
var_dump(
sodium_memcmp($clientSessionKeys['tx'], $serverSessionKeys['rx']) === 0, // true
sodium_memcmp($clientSessionKeys['rx'], $serverSessionKeys['tx']) === 0 // true
);
// Schlüssel nach Verwendung aus dem Speicher löschen
sodium_memzero($clientSessionKeys['rx']);
sodium_memzero($clientSessionKeys['tx']);
sodium_memzero($serverSessionKeys['rx']);
sodium_memzero($serverSessionKeys['tx']);
Verschlüsselte Kommunikation mit secretstream nach dem Schlüsselaustausch
<?php
// Voraussetzung: $clientKeypair und $serverPublicKey sind bekannt
$clientKeypair = sodium_crypto_kx_keypair();
$serverKeypair = sodium_crypto_kx_keypair();
$serverPublicKey = sodium_crypto_kx_publickey($serverKeypair);
$clientPublicKey = sodium_crypto_kx_publickey($clientKeypair);
// Sitzungsschlüssel erzeugen
$clientKeys = sodium_crypto_kx_client_session_keys($clientKeypair, $serverPublicKey);
$serverKeys = sodium_crypto_kx_server_session_keys($serverKeypair, $clientPublicKey);
// Client verschlüsselt eine Nachricht mit seinem TX-Schlüssel
[$state, $header] = sodium_crypto_secretstream_xchacha20poly1305_init_push($clientKeys['tx']);
$ciphertext = sodium_crypto_secretstream_xchacha20poly1305_push($state, 'Geheime Nachricht');
// Server entschlüsselt mit seinem RX-Schlüssel (entspricht Client-TX)
$serverState = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $serverKeys['rx']);
[$plaintext, $tag] = sodium_crypto_secretstream_xchacha20poly1305_pull($serverState, $ciphertext);
echo $plaintext;
// Wichtig · Fallstricke
Sicherheitshinweise:
- Das
client_keypairenthält den privaten Schlüssel und muss streng vertraulich behandelt werden. Es darf niemals übertragen oder unsicher gespeichert werden. - Nach der Verwendung sollten die Sitzungsschlüssel mit
sodium_memzero()aus dem Arbeitsspeicher gelöscht werden, um Speicher-Dump-Angriffe zu erschweren. - Der öffentliche Schlüssel des Servers sollte über einen authentisierten Kanal ausgetauscht oder vorab bekannt sein (z. B. per Certificate Pinning), um Man-in-the-Middle-Angriffe zu verhindern.
- Die Funktion wirft eine
SodiumException, wenn die Schlüssellängen nicht den erwarteten KonstantenSODIUM_CRYPTO_KX_KEYPAIRBYTESbzw.SODIUM_CRYPTO_KX_PUBLICKEYBYTESentsprechen.