Start · Sprachen · PHP · Referenz · openssl_public_decrypt

openssl_public_decrypt

Funktion

Entschlüsselt Daten, die zuvor mit dem zugehörigen privaten Schlüssel verschlüsselt wurden, mithilfe eines öffentlichen Schlüssels.

seit PHP 4.0.6 Kategorie: crypto

Signatur

openssl_public_decrypt(string $data, string &$decrypted, OpenSSLAsymmetricKey|string $public_key, int $padding = OPENSSL_PKCS1_PADDING): bool

Beschreibung

openssl_public_decrypt kehrt den Vorgang von openssl_private_encrypt um: Ein Sender verschlüsselt Daten mit seinem privaten Schlüssel (z. B. zur digitalen Signatur oder zur Nachweisbarkeit der Herkunft), und der Empfänger entschlüsselt sie mit dem zugehörigen öffentlichen Schlüssel. Das ist das Gegenteil der klassischen asymmetrischen Verschlüsselung, bei der der öffentliche Schlüssel zum Verschlüsseln und der private zum Entschlüsseln verwendet wird.

Dieses Muster wird typischerweise für primitive digitale Signaturen oder zur Authentifizierung eingesetzt, wenn man sicherstellen möchte, dass die Daten nur von jemandem mit Zugang zum privaten Schlüssel erzeugt worden sein können. Für produktionsreife Signaturen sollte jedoch openssl_sign / openssl_verify bevorzugt werden, da diese einen sicheren Hash-Algorithmus verwenden.

Der Parameter padding muss mit dem bei der Verschlüsselung verwendeten Padding übereinstimmen. Am häufigsten wird OPENSSL_PKCS1_PADDING verwendet. Für No-Padding (OPENSSL_NO_PADDING) sind besondere Vorkenntnisse erforderlich, da unsicherer Umgang zu Sicherheitslücken führt.

Ab PHP 8.0 akzeptiert public_key ein OpenSSLAsymmetricKey-Objekt (zurückgegeben von openssl_get_publickey); in älteren Versionen war es eine Ressource. Ein String im PEM-Format wird ebenfalls akzeptiert.

Parameter

Name Typ Default Beschreibung
$data Pflicht string Die verschlüsselten Binärdaten, die entschlüsselt werden sollen. Diese müssen zuvor mit openssl_private_encrypt und dem zugehörigen privaten Schlüssel verschlüsselt worden sein.
$decrypted Pflicht string Referenz auf eine Variable, in die der entschlüsselte Klartext geschrieben wird. Der vorherige Inhalt der Variable wird überschrieben.
$public_key Pflicht OpenSSLAsymmetricKey|string Der öffentliche Schlüssel als OpenSSLAsymmetricKey-Objekt (PHP 8.0+), als Ressource (ältere PHP-Versionen) oder als PEM-kodierter String.
$padding int OPENSSL_PKCS1_PADDING Das Padding-Verfahren. Mögliche Werte: OPENSSL_PKCS1_PADDING, OPENSSL_NO_PADDING. Muss mit dem bei der Verschlüsselung verwendeten Padding übereinstimmen.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn die Entschlüsselung erfolgreich war, andernfalls false. Im Fehlerfall (z. B. falscher Schlüssel oder falsches Padding) bleibt $decrypted unverändert oder leer.

Beispiele

Nachrichten-Entschlüsselung mit privatem Verschlüsseler und öffentlichem Entschlüsseler

<?php
// Schlüsselpaar erzeugen
$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 exportieren
$keyDetails = openssl_pkey_get_details($keyPair);
$publicKeyPem = $keyDetails['key'];

$message = 'Authentische Nachricht vom Sender';

// Sender: Verschlüsselt mit privatem Schlüssel ("signiert")
$privateKey = openssl_pkey_get_private($privateKeyPem);
openssl_private_encrypt($message, $encrypted, $privateKey);

echo 'Verschlüsselt (base64): ' . base64_encode($encrypted) . PHP_EOL;

// Empfänger: Entschlüsselt mit öffentlichem Schlüssel
$publicKey = openssl_pkey_get_public($publicKeyPem);
$success = openssl_public_decrypt($encrypted, $decrypted, $publicKey);

if ($success) {
    echo 'Entschlüsselte Nachricht: ' . $decrypted . PHP_EOL;
} else {
    echo 'Entschlüsselung fehlgeschlagen.' . PHP_EOL;
}
Verschlüsselt (base64): <base64-kodierter Binärstring> Entschlüsselte Nachricht: Authentische Nachricht vom Sender

Verifikation: Ungültiger Schlüssel schlägt fehl

<?php
// Zwei verschiedene Schlüsselpaare erzeugen
$keyPairA = openssl_pkey_new(['private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA]);
$keyPairB = openssl_pkey_new(['private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA]);

openssl_pkey_export($keyPairA, $privateKeyA);
$detailsB = openssl_pkey_get_details($keyPairB);
$publicKeyB = $detailsB['key'];

$message = 'Test';

// Mit privatem Schlüssel A verschlüsseln
openssl_private_encrypt($message, $encrypted, openssl_pkey_get_private($privateKeyA));

// Versuch, mit öffentlichem Schlüssel B zu entschlüsseln (falsches Paar!)
$result = openssl_public_decrypt($encrypted, $decrypted, openssl_pkey_get_public($publicKeyB));

var_dump($result); // bool(false) — Schlüssel passt nicht zusammen
bool(false)

// Wichtig · Fallstricke

Sicherheitshinweis: Die Kombination openssl_private_encrypt + openssl_public_decrypt ist kein Ersatz für kryptografisch sichere digitale Signaturen. Sie bietet keinen Schutz vor Längen- oder Padding-Angriffen. Für echte Signatur-/Verifikations-Szenarien sollten openssl_sign und openssl_verify verwendet werden.

OPENSSL_NO_PADDING sollte nur von Experten verwendet werden, da es anfällig für mathematische Angriffe auf RSA ist (z. B. Bleichenbacher-Angriff in Varianten).

Ab PHP 8.0 wurden OpenSSL-Ressourcen durch das Objekt OpenSSLAsymmetricKey ersetzt. Code, der openssl_pkey_get_public() in PHP 7.x nutzt, liefert eine Ressource — das Verhalten von openssl_public_decrypt ist kompatibel, aber der Typ unterscheidet sich.