Start · Sprachen · PHP · Referenz · openssl_private_decrypt

openssl_private_decrypt

Funktion

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

seit PHP 4.0.6 Kategorie: crypto

Signatur

openssl_private_decrypt(string $data, string &$decrypted, OpenSSLAsymmetricKey|array|string $private_key, int $padding = OPENSSL_PKCS1_PADDING): bool

Beschreibung

openssl_private_decrypt entschlüsselt einen Datenpuffer, der mit openssl_public_encrypt (oder einem kompatiblen Verfahren) verschlüsselt wurde. Das Ergebnis wird in der per Referenz übergebenen Variable $decrypted gespeichert. Diese Funktion ist Teil des asymmetrischen RSA-Verschlüsselungsmusters: Verschlüsseln mit dem öffentlichen Schlüssel, Entschlüsseln mit dem privaten Schlüssel.

Typische Einsatzszenarien sind der Empfang vertraulicher Daten von Dritten (z. B. Passwörter, Session-Tokens oder symmetrische Schlüssel), die für den eigenen öffentlichen Schlüssel verschlüsselt wurden. Da RSA direkt nur für kleine Datenmengen geeignet ist, wird in der Praxis oft ein hybrides Verfahren verwendet: Ein symmetrischer AES-Schlüssel wird per RSA übertragen, während die eigentlichen Nutzdaten mit AES verschlüsselt werden.

Der $padding-Parameter bestimmt das verwendete Padding-Verfahren. Standardmäßig wird OPENSSL_PKCS1_PADDING verwendet, was für die meisten Anwendungsfälle korrekt ist. OAEP-Padding (OPENSSL_PKCS1_OAEP_PADDING) bietet eine höhere Sicherheit und sollte für neue Implementierungen bevorzugt werden. OPENSSL_NO_PADDING sollte nur von Experten verwendet werden, da es bei falscher Handhabung zu schwerwiegenden Sicherheitslücken führen kann.

Der private Schlüssel kann als OpenSSLAsymmetricKey-Ressource (erzeugt mit openssl_get_privatekey), als Array ["key", "passphrase"] oder als PEM-kodierter String übergeben werden.

Parameter

Name Typ Default Beschreibung
$data Pflicht string Der zu entschlüsselnde Datenpuffer, typischerweise die mit openssl_public_encrypt verschlüsselten Rohdaten (binär).
$decrypted Pflicht string Ausgabe-Variable, die nach erfolgreicher Entschlüsselung den Klartext enthält. Wird per Referenz übergeben.
$private_key Pflicht OpenSSLAsymmetricKey|array|string Der private Schlüssel als OpenSSLAsymmetricKey-Ressource, PEM-String oder Array [$pem_string, $passphrase] bei passwortgeschützten Schlüsseln.
$padding int OPENSSL_PKCS1_PADDING Das Padding-Verfahren. Mögliche Werte: OPENSSL_PKCS1_PADDING (Standard), OPENSSL_PKCS1_OAEP_PADDING (empfohlen für neue Implementierungen), OPENSSL_SSLV23_PADDING oder OPENSSL_NO_PADDING.

Rückgabewert

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

Beispiele

Einfache RSA-Verschlüsselung und -Entschlüsselung

<?php
// Schlüsselpaar erzeugen
$config = [
    'digest_alg'       => 'sha256',
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
];
$resource = openssl_pkey_new($config);

// Öffentlichen und privaten Schlüssel extrahieren
$keyDetails = openssl_pkey_get_details($resource);
$publicKey  = $keyDetails['key'];

openssl_pkey_export($resource, $privateKey);

// Daten mit dem öffentlichen Schlüssel verschlüsseln
$plaintext = 'Geheime Nachricht';
openssl_public_encrypt($plaintext, $encrypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);

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

// Daten mit dem privaten Schlüssel entschlüsseln
if (openssl_private_decrypt($encrypted, $decrypted, $privateKey, OPENSSL_PKCS1_OAEP_PADDING)) {
    echo 'Entschlüsselt: ' . $decrypted . PHP_EOL;
} else {
    echo 'Entschlüsselung fehlgeschlagen.' . PHP_EOL;
}
Verschlüsselt (Base64): <base64-kodierter Binärstring> Entschlüsselt: Geheime Nachricht

Hybride Verschlüsselung: AES-Schlüssel per RSA übertragen

<?php
// Vorausgesetzt: $privateKeyPem enthält den privaten PEM-Schlüssel des Empfängers
// $encryptedAesKey enthält den per RSA verschlüsselten AES-Schlüssel
// $iv und $ciphertext enthalten die AES-verschlüsselte Nachricht

$privateKey = openssl_get_privatekey($privateKeyPem, 'optionales_passwort');

if (!$privateKey) {
    throw new RuntimeException('Privater Schlüssel konnte nicht geladen werden.');
}

// AES-Schlüssel per RSA entschlüsseln
if (!openssl_private_decrypt($encryptedAesKey, $aesKey, $privateKey, OPENSSL_PKCS1_OAEP_PADDING)) {
    throw new RuntimeException('RSA-Entschlüsselung des AES-Schlüssels fehlgeschlagen.');
}

// Nachricht mit entschlüsseltem AES-Schlüssel entschlüsseln
$message = openssl_decrypt(
    $ciphertext,
    'aes-256-cbc',
    $aesKey,
    OPENSSL_RAW_DATA,
    $iv
);

echo 'Empfangene Nachricht: ' . $message;
Empfangene Nachricht: <entschlüsselte Nutzdaten>

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Verwende für neue Implementierungen stets OPENSSL_PKCS1_OAEP_PADDING statt des Standard-PKCS#1-v1.5-Paddings, da letzteres anfällig für Bleichenbacher-Angriffe (Padding-Oracle) ist.
  • OPENSSL_NO_PADDING darf nur von kryptografischen Experten eingesetzt werden, da es ohne Padding-Schutz zu schwerwiegenden Sicherheitslücken führen kann.
  • RSA ist nur für kleine Datenmengen geeignet (maximal Schlüssellänge minus Padding-Overhead). Für größere Daten ist das hybride Verfahren (RSA + AES) die richtige Wahl.
  • Private Schlüssel sollten niemals im Quellcode hartcodiert, sondern aus sicheren Speicherorten (Dateisystem mit restriktiven Rechten, HSM, Vault) geladen werden.
  • Seit PHP 8.0 sind OpenSSL-Schlüssel-Ressourcen Instanzen von OpenSSLAsymmetricKey statt des früheren resource-Typs.