Start · Sprachen · PHP · Referenz · openssl_sign

openssl_sign

Funktion

Erzeugt eine kryptografische Signatur für die übergebenen Daten mithilfe eines privaten Schlüssels.

seit PHP 4.0.4 Kategorie: crypto

Signatur

openssl_sign(string $data, string &$signature, OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key, string|int $algorithm = OPENSSL_ALGO_SHA256): bool

Beschreibung

openssl_sign() berechnet eine digitale Signatur für den String $data unter Verwendung des angegebenen privaten Schlüssels und des gewählten Hash-Algorithmus. Die erzeugte Signatur wird in die Variable $signature geschrieben (per Referenz). Digitale Signaturen ermöglichen es Empfängern, die Authentizität und Integrität einer Nachricht zu überprüfen, ohne den privaten Schlüssel zu besitzen.

Der Einsatz ist typisch bei der Absicherung von API-Anfragen, der Signierung von JWT-Tokens, der Dokumentensignierung oder überall dort, wo nachgewiesen werden muss, dass Daten von einer bestimmten Partei stammen und nicht verändert wurden. Die Gegenstelle verifiziert die Signatur mit dem zugehörigen öffentlichen Schlüssel mithilfe von openssl_verify().

Als Algorithmus können Konstanten wie OPENSSL_ALGO_SHA256, OPENSSL_ALGO_SHA512, OPENSSL_ALGO_SHA1 oder Algorithmus-Namen als String (z. B. 'sha384WithRSAEncryption') übergeben werden. Von OPENSSL_ALGO_SHA1 und schwächeren Algorithmen ist aus Sicherheitsgründen abzuraten; OPENSSL_ALGO_SHA256 oder stärker ist empfohlen.

Der private Schlüssel kann als OpenSSLAsymmetricKey-Ressource (erzeugt via openssl_pkey_get_private()), als PEM-String, als Dateiname mit dem Präfix file:// oder als Array in der Form [$key, $passphrase] übergeben werden.

Parameter

Name Typ Default Beschreibung
$data Pflicht string Die zu signierenden Daten als String. Es werden die rohen Bytes signiert; bei langen Daten empfiehlt sich ggf. vorheriges Hashing.
$signature Pflicht string Referenz auf eine Variable, in die die erzeugte Binär-Signatur geschrieben wird. Für die Übertragung sollte sie anschließend z. B. mit base64_encode() kodiert werden.
$private_key Pflicht OpenSSLAsymmetricKey|OpenSSLCertificate|array|string Der private Schlüssel zum Signieren. Akzeptiert ein OpenSSLAsymmetricKey-Objekt, einen PEM-kodierten String, einen Dateipfad mit file://-Präfix oder ein Array [$key, $passphrase] für passwortgeschützte Schlüssel.
$algorithm string|int OPENSSL_ALGO_SHA256 Hash-Algorithmus als Konstante (z. B. OPENSSL_ALGO_SHA256) oder als String-Name (z. B. 'sha256WithRSAEncryption'). Verfügbare Algorithmen können mit openssl_get_md_methods() abgefragt werden.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn die Signatur erfolgreich erzeugt wurde, andernfalls false (z. B. bei ungültigem Schlüssel oder nicht unterstütztem Algorithmus). Im Fehlerfall können weitere Informationen mit openssl_error_string() abgerufen werden.

Beispiele

Einfache Datensignierung und Verifikation

<?php
// Schlüsselpaar erzeugen (nur für Demo; normalerweise aus Datei laden)
$keyPair = openssl_pkey_new([
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);

// Privaten Schlüssel exportieren
openssl_pkey_export($keyPair, $privateKeyPem);

// Öffentlichen Schlüssel holen
$publicKeyDetails = openssl_pkey_get_details($keyPair);
$publicKeyPem = $publicKeyDetails['key'];

$data = 'Wichtige Nachricht, die signiert werden soll.';

// Daten signieren
$signature = '';
$result = openssl_sign($data, $signature, $privateKeyPem, OPENSSL_ALGO_SHA256);

if ($result) {
    echo "Signatur erzeugt (Base64): " . base64_encode($signature) . PHP_EOL;
} else {
    echo "Fehler beim Signieren: " . openssl_error_string() . PHP_EOL;
}

// Signatur verifizieren
$publicKey = openssl_pkey_get_public($publicKeyPem);
$verified = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);

if ($verified === 1) {
    echo "Signatur ist gültig." . PHP_EOL;
} elseif ($verified === 0) {
    echo "Signatur ist UNGÜLTIG." . PHP_EOL;
} else {
    echo "Fehler bei der Verifikation: " . openssl_error_string() . PHP_EOL;
}
Signatur erzeugt (Base64): <Base64-kodierte Signatur> Signatur ist gültig.

Signierung mit passwortgeschütztem PEM-Schlüssel aus Datei

<?php
$data = json_encode(['user_id' => 42, 'action' => 'purchase', 'amount' => 99.95]);

// Passwortgeschützten privaten Schlüssel laden
$privateKey = openssl_pkey_get_private(
    'file:///pfad/zum/private_key.pem',
    'meinGeheimesPasswort'
);

if ($privateKey === false) {
    die('Schlüssel konnte nicht geladen werden: ' . openssl_error_string());
}

$signature = '';
if (openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA512)) {
    // Signatur base64url-kodiert (für URLs geeignet)
    $signatureB64 = rtrim(strtr(base64_encode($signature), '+/', '-_'), '=');
    echo "Payload: " . $data . PHP_EOL;
    echo "Signatur (Base64URL): " . $signatureB64 . PHP_EOL;
} else {
    echo "Fehler: " . openssl_error_string() . PHP_EOL;
}
Payload: {"user_id":42,"action":"purchase","amount":99.95} Signatur (Base64URL): <Base64URL-kodierte Signatur>

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Verwende mindestens OPENSSL_ALGO_SHA256; ältere Algorithmen wie OPENSSL_ALGO_SHA1 oder OPENSSL_ALGO_MD5 gelten als unsicher und sollten nicht mehr eingesetzt werden.
  • Schütze private Schlüssel sorgfältig: niemals in öffentlich zugänglichen Verzeichnissen ablegen, Zugriffsrechte restriktiv setzen und Passwörter für Schlüsseldateien sicher verwalten (z. B. via Umgebungsvariablen).
  • Die erzeugte Signatur enthält Binärdaten. Vor der Übertragung via HTTP, E-Mail oder JSON muss sie mit base64_encode() oder für URLs mit Base64URL-Kodierung umgewandelt werden.
  • Ab PHP 8.0 werden OpenSSL-Schlüssel als Objekte (OpenSSLAsymmetricKey) statt als Ressourcen zurückgegeben. Der Code ist aber weitgehend kompatibel.
  • Bei Fehlern gibt die Funktion false zurück; nutze openssl_error_string() in einer Schleife, um alle ausstehenden Fehler aus dem OpenSSL-Fehler-Stack zu lesen.