Start · Sprachen · PHP · Referenz · sodium_crypto_kx_server_session_keys

sodium_crypto_kx_server_session_keys

Funktion

Berechnet aus dem serverseitigen Schlüsselpaar und dem öffentlichen Schlüssel des Clients die serverseitigen Sitzungsschlüssel für einen sicheren Schlüsselaustausch.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_kx_server_session_keys(string $server_keypair, string $client_public_key): array

Beschreibung

sodium_crypto_kx_server_session_keys() ist Teil des Libsodium-Schlüsselaustausch-Protokolls (Key Exchange, KX) und berechnet zwei symmetrische Sitzungsschlüssel aus der Perspektive des Servers. Das Protokoll basiert auf dem X25519-Diffie-Hellman-Verfahren und liefert getrennte Schlüssel für eingehende (receive) und ausgehende (send) Daten.

Das Ergebnis ist ein assoziatives Array mit zwei Schlüsseln: receive enthält den Sitzungsschlüssel, mit dem der Server eingehende (vom Client gesendete) Nachrichten entschlüsselt, und send enthält den Schlüssel, mit dem der Server ausgehende Nachrichten an den Client verschlüsselt. Auf der Clientseite sind diese Rollen vertauscht – der Client verschlüsselt mit seinem send-Schlüssel, was dem receive-Schlüssel des Servers entspricht.

Typischerweise wird dieses Protokoll zusammen mit sodium_crypto_kx_server_session_keys() (Server) und sodium_crypto_kx_client_session_keys() (Client) eingesetzt: Beide Seiten tauschen zunächst ihre öffentlichen Schlüssel aus und berechnen dann unabhängig voneinander dieselben Sitzungsschlüssel. Diese können anschließend für symmetrische Verschlüsselung, z. B. mit sodium_crypto_secretstream_xchacha20poly1305, verwendet werden.

Der Server-Schlüsselpaar-Parameter muss mit sodium_crypto_kx_keypair() oder sodium_crypto_kx_seed_keypair() erzeugt worden sein und enthält sowohl den privaten als auch den öffentlichen Schlüssel des Servers.

Parameter

Name Typ Default Beschreibung
$server_keypair Pflicht string Das vollständige Schlüsselpaar des Servers (privater + öffentlicher Schlüssel), erzeugt durch sodium_crypto_kx_keypair() oder sodium_crypto_kx_seed_keypair(). Die Länge muss exakt SODIUM_CRYPTO_KX_KEYPAIRBYTES betragen.
$client_public_key Pflicht string Der öffentliche Schlüssel des Clients, der zuvor über einen authentifizierten Kanal (z. B. TLS) übermittelt wurde. Die Länge muss exakt SODIUM_CRYPTO_KX_PUBLICKEYBYTES betragen.

Rückgabewert

Typ
array
Beschreibung
Gibt ein assoziatives Array mit zwei Elementen zurück: receive (String) – Sitzungsschlüssel zum Entschlüsseln eingehender Client-Nachrichten; send (String) – Sitzungsschlüssel zum Verschlüsseln ausgehender Nachrichten an den Client. Beide Schlüssel sind je SODIUM_CRYPTO_KX_SESSIONKEYBYTES Bytes lang. Bei ungültigen Eingabeparametern wird eine SodiumException geworfen.

Beispiele

Schlüsselaustausch zwischen Server und Client

<?php
// --- Server-Seite ---
$serverKeypair = sodium_crypto_kx_keypair();
$serverPublicKey = sodium_crypto_kx_publickey($serverKeypair);

// --- Client-Seite ---
$clientKeypair = sodium_crypto_kx_keypair();
$clientPublicKey = sodium_crypto_kx_publickey($clientKeypair);

// Client berechnet seine Sitzungsschlüssel
$clientKeys = sodium_crypto_kx_client_session_keys($clientKeypair, $serverPublicKey);

// Server berechnet seine Sitzungsschlüssel
$serverKeys = sodium_crypto_kx_server_session_keys($serverKeypair, $clientPublicKey);

// Überprüfung: Die Schlüssel sind spiegelverkehrt identisch
var_dump(sodium_memcmp($clientKeys['send'], $serverKeys['receive']) === 0); // true
var_dump(sodium_memcmp($clientKeys['receive'], $serverKeys['send']) === 0); // true

echo "Sitzungsschlüssel erfolgreich ausgetauscht!\n";
bool(true) bool(true) Sitzungsschlüssel erfolgreich ausgetauscht!

Verschlüsselter Nachrichtenaustausch nach KX

<?php
// Schlüsselpaare erzeugen
$serverKeypair = sodium_crypto_kx_keypair();
$clientKeypair = sodium_crypto_kx_keypair();

$serverPublicKey = sodium_crypto_kx_publickey($serverKeypair);
$clientPublicKey = sodium_crypto_kx_publickey($clientKeypair);

// Sitzungsschlüssel berechnen
$serverKeys = sodium_crypto_kx_server_session_keys($serverKeypair, $clientPublicKey);
$clientKeys = sodium_crypto_kx_client_session_keys($clientKeypair, $serverPublicKey);

// Client verschlüsselt eine Nachricht mit seinem 'send'-Schlüssel
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$plaintext = 'Hallo Server, geheime Nachricht!';
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $clientKeys['send']);

// Server entschlüsselt mit seinem 'receive'-Schlüssel
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $serverKeys['receive']);

echo $decrypted; // Hallo Server, geheime Nachricht!

// Schlüssel nach Gebrauch aus dem Speicher löschen
sodium_memzero($serverKeys['receive']);
sodium_memzero($serverKeys['send']);
sodium_memzero($clientKeys['receive']);
sodium_memzero($clientKeys['send']);
Hallo Server, geheime Nachricht!

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Der öffentliche Schlüssel des Clients (client_public_key) sollte über einen bereits authentifizierten Kanal übertragen werden, da das KX-Protokoll selbst keine Authentizität des Schlüssels garantiert. Andernfalls besteht die Gefahr eines Man-in-the-Middle-Angriffs.
  • Sitzungsschlüssel sollten nach Verwendung mit sodium_memzero() aus dem Speicher gelöscht werden, um deren Verweildauer im RAM zu minimieren.
  • Niemals denselben Sitzungsschlüssel für mehrere unabhängige Sitzungen wiederverwenden. Bei jeder neuen Verbindung müssen neue Schlüsselpaare bzw. neue Sitzungsschlüssel erzeugt werden.
  • Bei ungültigen Schlüssellängen wirft die Funktion eine SodiumException – diese sollte stets abgefangen werden.