Start · Sprachen · PHP · Referenz · sodium_crypto_scalarmult

sodium_crypto_scalarmult

Funktion

Berechnet ein gemeinsames Geheimnis (Shared Secret) aus einem geheimen Schlüssel und einem öffentlichen Schlüssel mittels Diffie-Hellman-Schlüsselaustausch auf Curve25519.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_scalarmult(string $n, string $p): string

Beschreibung

sodium_crypto_scalarmult implementiert die X25519-Skalarmultiplikation (Diffie-Hellman auf Curve25519). Übergeben wird der eigene geheime Schlüssel ($n) und der öffentliche Schlüssel der Gegenseite ($p). Das Ergebnis ist ein 32-Byte-Rohwert, der als Basis für weitere kryptografische Operationen – typischerweise zum Ableiten eines symmetrischen Schlüssels – genutzt werden kann.

Dieses Verfahren eignet sich für den Aufbau eines gemeinsamen Geheimnisses zwischen zwei Parteien, ohne dass ein geheimer Kanal benötigt wird. Beide Seiten berechnen aus ihrem eigenen geheimen und dem öffentlichen Schlüssel der anderen Seite dasselbe Ergebnis, ohne das Geheimnis je direkt zu übertragen (ECDH).

Wichtig: Der Rückgabewert ist kein fertiger Schlüssel, sondern sollte durch eine geeignete Schlüsselableitungsfunktion (KDF) wie sodium_crypto_kdf_derive_from_key oder sodium_crypto_generichash weiterverarbeitet werden, bevor er als symmetrischer Schlüssel verwendet wird. Das direkte Verwenden des Rohwerts als Schlüssel wird nicht empfohlen.

Schlüsselpaare für dieses Verfahren können mit sodium_crypto_box_keypair oder sodium_crypto_kx_keypair erzeugt werden. Die Schlüssellängen sind durch die Konstanten SODIUM_CRYPTO_SCALARMULT_SCALARBYTES (32) und SODIUM_CRYPTO_SCALARMULT_BYTES (32) definiert.

Parameter

Name Typ Default Beschreibung
$n Pflicht string Der eigene geheime Schlüssel (Scalar) als Binärstring. Muss exakt SODIUM_CRYPTO_SCALARMULT_SCALARBYTES (32) Byte lang sein.
$p Pflicht string Der öffentliche Schlüssel der Gegenseite (Punkt auf der Kurve) als Binärstring. Muss exakt SODIUM_CRYPTO_SCALARMULT_BYTES (32) Byte lang sein.

Rückgabewert

Typ
string
Beschreibung
Gibt das berechnete gemeinsame Geheimnis als Binärstring mit 32 Byte zurück. Bei ungültigen Parametern (falsche Länge) wird eine SodiumException geworfen.

Beispiele

ECDH-Schlüsselaustausch zwischen Alice und Bob

<?php
// Alice erzeugt ihr Schlüsselpaar
$alice = sodium_crypto_box_keypair();
$alice_secret = sodium_crypto_box_secretkey($alice);
$alice_public = sodium_crypto_box_publickey($alice);

// Bob erzeugt sein Schlüsselpaar
$bob = sodium_crypto_box_keypair();
$bob_secret = sodium_crypto_box_secretkey($bob);
$bob_public = sodium_crypto_box_publickey($bob);

// Alice berechnet das gemeinsame Geheimnis mit Bobs öffentlichem Schlüssel
$shared_alice = sodium_crypto_scalarmult($alice_secret, $bob_public);

// Bob berechnet das gemeinsame Geheimnis mit Alices öffentlichem Schlüssel
$shared_bob = sodium_crypto_scalarmult($bob_secret, $alice_public);

// Beide erhalten dasselbe Ergebnis
if (sodium_memcmp($shared_alice, $shared_bob) === 0) {
    echo "Gemeinsames Geheimnis stimmt überein!" . PHP_EOL;
}

// Rohwert als Hex (nur zur Demonstration, nicht direkt als Schlüssel verwenden)
echo bin2hex($shared_alice) . PHP_EOL;
Gemeinsames Geheimnis stimmt überein! (32-Byte-Hex-Wert)

Ableitung eines symmetrischen Schlüssels aus dem Shared Secret

<?php
// Schlüsselpaare erzeugen (z. B. aus gespeicherten Werten laden)
$alice_keypair = sodium_crypto_kx_keypair();
$alice_secret  = sodium_crypto_kx_secretkey($alice_keypair);

$bob_keypair = sodium_crypto_kx_keypair();
$bob_public  = sodium_crypto_kx_publickey($bob_keypair);

// Gemeinsames Rohgeheimnis berechnen
$raw_shared = sodium_crypto_scalarmult($alice_secret, $bob_public);

// Schlüssel sicher ableiten (z. B. als 32-Byte-AES-Schlüssel)
$symmetric_key = sodium_crypto_generichash(
    $raw_shared,
    '', // kein Schlüssel für die Hash-Funktion
    SODIUM_CRYPTO_SECRETBOX_KEYBYTES // 32 Byte
);

echo 'Symmetrischer Schlüssel (Hex): ' . bin2hex($symmetric_key) . PHP_EOL;

// Rohdaten sicher aus dem Speicher löschen
sodium_memzero($raw_shared);
Symmetrischer Schlüssel (Hex): (64-stelliger Hex-Wert)

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Das Ergebnis von sodium_crypto_scalarmult sollte niemals direkt als Schlüssel für symmetrische Verschlüsselung verwendet werden. Leite stets einen Schlüssel mit einer KDF oder einem Hash ab.
  • Prüfe, ob der öffentliche Schlüssel der Gegenseite authentisch ist (z. B. durch Signaturen), um Man-in-the-Middle-Angriffe zu vermeiden.
  • Lösche vertrauliche Werte (geheimer Schlüssel, Shared Secret) nach Verwendung mit sodium_memzero() aus dem Arbeitsspeicher.
  • Für einen vollständigen, sicheren Schlüsselaustausch empfiehlt die libsodium-Dokumentation die Verwendung der Convenience-Funktion sodium_crypto_kx_*, die Sicherheitsaspekte wie Kontextbindung bereits berücksichtigt.
  • Ein Scalar-Wert von lauter Nullen liefert ein unsicheres Ergebnis (Kleiner-Untergruppen-Angriff); libsodium prüft dies intern und wirft ggf. eine Exception.