Start · Sprachen · PHP · Referenz · sodium_crypto_sign

sodium_crypto_sign

Funktion

Signiert eine Nachricht mit einem geheimen Ed25519-Schlüssel und gibt die signierte Nachricht (Signatur + Nachricht) zurück.

seit PHP 7.2.0 Kategorie: crypto

Signatur

sodium_crypto_sign(string $message, string $secret_key): string

Beschreibung

sodium_crypto_sign erzeugt eine digitale Signatur für eine Nachricht mithilfe des Ed25519-Algorithmus (Edwards-Curve Digital Signature Algorithm). Das Ergebnis ist eine kombinierte Ausgabe, die sowohl die 64-Byte-Signatur als auch die ursprüngliche Nachricht enthält – sogenannte combined mode-Ausgabe.

Diese Funktion eignet sich hervorragend für Szenarien, in denen Integrität und Authentizität einer Nachricht sichergestellt werden müssen, etwa bei signierten API-Tokens, verifizierbaren Nachrichten oder Software-Updates. Der Empfänger kann mit dem zugehörigen öffentlichen Schlüssel (sodium_crypto_sign_open) die Echtheit der Nachricht bestätigen.

Der geheime Schlüssel ($secret_key) hat eine Länge von SODIUM_CRYPTO_SIGN_SECRETKEYBYTES (64 Byte) und wird typischerweise mit sodium_crypto_sign_keypair erzeugt. Der zugehörige öffentliche Schlüssel lässt sich mit sodium_crypto_sign_publickey_from_secretkey extrahieren.

Wenn nur die Signatur ohne die Nachricht benötigt wird (z. B. für Protokolle, die Signatur und Nachricht separat übertragen), sollte stattdessen sodium_crypto_sign_detached verwendet werden.

Parameter

Name Typ Default Beschreibung
$message Pflicht string Die zu signierende Nachricht. Kann beliebige Binärdaten oder Texte enthalten.
$secret_key Pflicht string Der geheime Ed25519-Schlüssel mit einer Länge von SODIUM_CRYPTO_SIGN_SECRETKEYBYTES (64 Byte). Wird in der Regel mit sodium_crypto_sign_keypair generiert.

Rückgabewert

Typ
string
Beschreibung
Gibt einen Binärstring zurück, der die 64-Byte-Signatur gefolgt von der ursprünglichen Nachricht enthält (Gesamtlänge: strlen($message) + SODIUM_CRYPTO_SIGN_BYTES). Bei einem Fehler wird eine SodiumException geworfen.

Beispiele

Nachricht signieren und verifizieren

<?php
// Schlüsselpaar erzeugen
$keypair = sodium_crypto_sign_keypair();
$secretKey = sodium_crypto_sign_secretkey($keypair);
$publicKey = sodium_crypto_sign_publickey($keypair);

$message = 'Wichtige Nachricht: Bitte nicht verändern.';

// Nachricht signieren
$signedMessage = sodium_crypto_sign($message, $secretKey);

echo 'Signierte Nachricht (hex): ' . bin2hex($signedMessage) . PHP_EOL;

// Signatur verifizieren und ursprüngliche Nachricht extrahieren
$verified = sodium_crypto_sign_open($signedMessage, $publicKey);

if ($verified === false) {
    echo 'Signatur ungültig!' . PHP_EOL;
} else {
    echo 'Signatur gültig. Nachricht: ' . $verified . PHP_EOL;
}

// Schlüssel aus dem Speicher löschen
sodium_memzero($secretKey);
Signatur gültig. Nachricht: Wichtige Nachricht: Bitte nicht verändern.

Signierten Token für eine API erstellen und prüfen

<?php
// Einmalig: Schlüsselpaar persistent speichern (hier vereinfacht)
$keypair = sodium_crypto_sign_keypair();
$secretKey = sodium_crypto_sign_secretkey($keypair);
$publicKey = sodium_crypto_sign_publickey($keypair);

// Token-Payload erstellen
$payload = json_encode([
    'user_id' => 42,
    'role'    => 'admin',
    'expires' => time() + 3600,
]);

// Payload signieren und Base64-kodieren (für Transport geeignet)
$signedToken = sodium_bin2base64(
    sodium_crypto_sign($payload, $secretKey),
    SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING
);

echo 'Token: ' . $signedToken . PHP_EOL;

// Auf Empfängerseite: Token verifizieren
$decoded = sodium_base642bin($signedToken, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING);
$verifiedPayload = sodium_crypto_sign_open($decoded, $publicKey);

if ($verifiedPayload === false) {
    echo 'Token-Signatur ist ungültig!' . PHP_EOL;
} else {
    $data = json_decode($verifiedPayload, true);
    if ($data['expires'] < time()) {
        echo 'Token abgelaufen!' . PHP_EOL;
    } else {
        echo 'Authentifizierter Benutzer: ' . $data['user_id'] . PHP_EOL;
    }
}

sodium_memzero($secretKey);
Authentifizierter Benutzer: 42

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Der geheime Schlüssel ($secret_key) muss streng vertraulich behandelt werden. Nach der Verwendung sollte er mit sodium_memzero aus dem Speicher gelöscht werden.
  • Die Ausgabe im combined mode enthält die Nachricht im Klartext – es handelt sich ausdrücklich nicht um Verschlüsselung. Für Vertraulichkeit muss zusätzlich verschlüsselt werden, z. B. mit sodium_crypto_box oder sodium_crypto_secretbox.
  • Ed25519 ist deterministisch – gleiche Nachricht und gleicher Schlüssel erzeugen immer dieselbe Signatur. Das ist sicher, kann aber unter Umständen Timing-Analysen ermöglichen, wenn Signaturen verglichen werden.
  • Bei ungültigem Schlüssel oder anderen Fehlern wirft die Funktion eine SodiumException. Diese sollte immer gefangen werden.