Start · Sprachen · PHP · Referenz · openssl_open

openssl_open

Funktion

Entschlüsselt versiegelte (mit <code>openssl_seal</code> verschlüsselte) Daten mithilfe eines privaten Schlüssels.

seit PHP 4.0.4 Kategorie: crypto

Signatur

openssl_open(string $data, string &$output, string $encrypted_key, OpenSSLAsymmetricKey|array|string $private_key, string $cipher_algo, string $iv = ""): bool

Beschreibung

openssl_open ist das Gegenstück zu openssl_seal und realisiert das sogenannte Envelope Encryption-Verfahren: Die eigentlichen Nutzdaten wurden mit einem symmetrischen Sitzungsschlüssel verschlüsselt, der seinerseits asymmetrisch (mit dem öffentlichen Schlüssel des Empfängers) geschützt wurde. openssl_open entschlüsselt zunächst den Sitzungsschlüssel mit dem übergebenen privaten RSA-Schlüssel und verwendet ihn dann, um die eigentlichen Daten zu entschlüsseln.

Das Verfahren eignet sich besonders für den sicheren Austausch größerer Datenmengen, da die symmetrische Verschlüsselung (z. B. AES) deutlich schneller ist als reine asymmetrische Verfahren. openssl_seal erzeugt den verschlüsselten Sitzungsschlüssel und den Chiffretext; openssl_open kehrt diesen Prozess mit dem entsprechenden privaten Schlüssel um.

Ab PHP 8.0 wird der Schlüsselparameter als OpenSSLAsymmetricKey-Objekt übergeben (zuvor war es eine Ressource). Der Parameter $cipher_algo sollte explizit angegeben werden; der Standardwert RC4 ist veraltet und unsicher – moderne Anwendungen sollten AES-256-CBC oder ähnliche starke Algorithmen wählen.

Bei Algorithmen, die einen Initialisierungsvektor (IV) benötigen (z. B. CBC-Modus), muss der bei openssl_seal generierte IV ebenfalls übergeben werden. Der entschlüsselte Klartext wird in den per Referenz übergebenen Parameter $output geschrieben.

Parameter

Name Typ Default Beschreibung
$data Pflicht string Der verschlüsselte Chiffretext, wie er von openssl_seal zurückgegeben wurde.
$output Pflicht string Referenz-Parameter, in den der entschlüsselte Klartext geschrieben wird.
$encrypted_key Pflicht string Der verschlüsselte Sitzungsschlüssel, der vom entsprechenden Empfänger-Eintrag aus dem $sealed_keys-Array von openssl_seal stammt.
$private_key Pflicht OpenSSLAsymmetricKey|array|string Der private Schlüssel des Empfängers als OpenSSLAsymmetricKey-Objekt, als Array [key, passphrase] oder als PEM-kodierter String.
$cipher_algo Pflicht string Der symmetrische Verschlüsselungsalgorithmus, z. B. 'AES-256-CBC'. Muss identisch mit dem bei openssl_seal verwendeten Algorithmus sein.
$iv string Der Initialisierungsvektor (IV), der bei openssl_seal erzeugt wurde. Pflicht für Algorithmen im CBC-Modus oder andere IV-abhängige Modi.

Rückgabewert

Typ
bool
Beschreibung
Gibt true bei Erfolg zurück, false bei einem Fehler (z. B. falscher privater Schlüssel, falscher Algorithmus oder beschädigte Daten).

Beispiele

Daten versiegeln und wieder öffnen (AES-256-CBC)

<?php
// Schlüsselpaar generieren
$keyPair = openssl_pkey_new([
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);

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

// Klartext versiegeln
$plaintext = 'Geheime Nachricht: Treffen um Mitternacht!';
$sealedData = '';
$encryptedKeys = [];
$iv = '';

openssl_seal($plaintext, $sealedData, $encryptedKeys, [$publicKey], 'AES-256-CBC', $iv);

echo 'Versiegelte Daten (Base64): ' . base64_encode($sealedData) . PHP_EOL;

// Versiegelte Daten öffnen
$decrypted = '';
$success = openssl_open($sealedData, $decrypted, $encryptedKeys[0], $keyPair, 'AES-256-CBC', $iv);

if ($success) {
    echo 'Entschlüsselter Text: ' . $decrypted . PHP_EOL;
} else {
    echo 'Entschlüsselung fehlgeschlagen!' . PHP_EOL;
}
Versiegelte Daten (Base64): <base64-kodierter String> Entschlüsselter Text: Geheime Nachricht: Treffen um Mitternacht!

Empfang versiegelter Daten mit gespeichertem privaten Schlüssel (PEM)

<?php
// Privaten Schlüssel aus Datei laden (passwortgeschützt)
$privateKeyPem = file_get_contents('/pfad/zum/private.pem');
$privateKey = openssl_pkey_get_private($privateKeyPem, 'meinPasswort');

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

// Empfangene (z. B. aus Datenbank gelesene) Daten
$sealedData    = base64_decode($_POST['sealed_data']);
$encryptedKey  = base64_decode($_POST['encrypted_key']);
$iv            = base64_decode($_POST['iv']);

$output = '';
if (openssl_open($sealedData, $output, $encryptedKey, $privateKey, 'AES-256-CBC', $iv)) {
    echo 'Erfolgreich entschlüsselt: ' . htmlspecialchars($output);
} else {
    echo 'Fehler beim Entschlüsseln: ' . openssl_error_string();
}

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Verwenden Sie niemals den veralteten Algorithmus RC4 (ehemaliger Standard). Setzen Sie stattdessen auf AES-256-CBC oder AES-256-GCM.
  • Der IV muss für jede Verschlüsselung einzigartig und zufällig sein. Er wird automatisch von openssl_seal generiert und muss sicher übertragen und gespeichert werden – er ist nicht geheim, aber entscheidend für die korrekte Entschlüsselung.
  • Bei GCM-Modus fehlt in PHP derzeit eine native Authentifizierungs-Tag-Prüfung über openssl_seal/openssl_open. Für authentifizierte Verschlüsselung empfehlen sich ggf. openssl_encrypt/openssl_decrypt mit explizitem Tag.
  • Prüfen Sie den Rückgabewert immer auf false und werten Sie openssl_error_string() im Fehlerfall aus.
  • Ab PHP 8.0 ist der Schlüssel-Parameter ein OpenSSLAsymmetricKey-Objekt; der frühere Ressource-Typ ist entfernt worden.