Start · Sprachen · PHP · Referenz · openssl_seal

openssl_seal

Funktion

Versiegelt (verschlüsselt) Daten mit einem zufälligen Sitzungsschlüssel, der seinerseits mit einem oder mehreren öffentlichen RSA-Schlüsseln verschlüsselt wird.

seit PHP 4.0.4 Kategorie: crypto

Signatur

openssl_seal(string $data, string &$sealed_data, array &$encrypted_keys, array $public_key, string $cipher_algo, string &$iv = ""): int|false

Beschreibung

openssl_seal() implementiert ein hybrides Verschlüsselungsverfahren: Die eigentlichen Nutzdaten werden mit einem zufällig generierten symmetrischen Sitzungsschlüssel und dem angegebenen Cipher-Algorithmus (z. B. AES-256-CBC) verschlüsselt. Anschließend wird dieser Sitzungsschlüssel für jeden übergebenen öffentlichen Schlüssel separat mit RSA verschlüsselt und in $encrypted_keys abgelegt.

Dieses Verfahren ist besonders dann sinnvoll, wenn dieselbe Nachricht an mehrere Empfänger gesendet werden soll, die jeweils ihren eigenen privaten Schlüssel besitzen. Jeder Empfänger kann seinen verschlüsselten Sitzungsschlüssel mit openssl_open() und seinem privaten Schlüssel entschlüsseln und so die Nutzdaten wiederherstellen.

Ab PHP 8.0 ist der Parameter $cipher_algo ein Pflichtparameter. Es wird dringend empfohlen, einen modernen Algorithmus wie AES-256-CBC zu verwenden und den erzeugten Initialisierungsvektor ($iv) zusammen mit den versiegelten Daten und den verschlüsselten Schlüsseln zu speichern, da er zur Entschlüsselung benötigt wird.

Die Funktion eignet sich für Szenarien wie sichere E-Mail-Systeme, Ende-zu-Ende-Verschlüsselung oder den sicheren Austausch großer Datenmengen, bei denen die Stärke asymmetrischer Kryptografie mit der Effizienz symmetrischer Verschlüsselung kombiniert werden soll.

Parameter

Name Typ Default Beschreibung
$data Pflicht string Die zu versiegelnden (zu verschlüsselnden) Klartextdaten.
$sealed_data Pflicht string Ausgabe-Parameter, der nach dem Aufruf die mit dem symmetrischen Sitzungsschlüssel verschlüsselten Daten enthält (per Referenz).
$encrypted_keys Pflicht array Ausgabe-Parameter als Array, das nach dem Aufruf für jeden übergebenen öffentlichen Schlüssel den entsprechend mit RSA verschlüsselten Sitzungsschlüssel enthält (per Referenz).
$public_key Pflicht array Array von OpenSSLAsymmetricKey-Objekten (oder vor PHP 8.0 von Ressourcen), die die öffentlichen RSA-Schlüssel der Empfänger repräsentieren. Kann auch einen einzigen Schlüssel als Array mit einem Element enthalten.
$cipher_algo Pflicht string Der zu verwendende symmetrische Verschlüsselungsalgorithmus, z. B. AES-256-CBC. Vor PHP 8.0 war der Standardwert RC4, was jedoch unsicher ist und nicht mehr verwendet werden sollte.
$iv string "" Ausgabe-Parameter, der nach dem Aufruf den generierten Initialisierungsvektor (IV) enthält (per Referenz). Der IV ist für die spätere Entschlüsselung mit openssl_open() zwingend erforderlich und muss zusammen mit den versiegelten Daten gespeichert werden.

Rückgabewert

Typ
int|false
Beschreibung
Gibt die Länge der versiegelten Daten in Bytes als int zurück. Bei einem Fehler wird false zurückgegeben.

Beispiele

Nachricht für einen einzelnen Empfänger versiegeln

<?php
// Schlüsselpaar erzeugen (normalerweise bereits vorhanden)
$keyPair = openssl_pkey_new([
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);
$publicKeyDetails = openssl_pkey_get_details($keyPair);
$publicKey = openssl_pkey_get_public($publicKeyDetails['key']);

$plaintext = 'Geheime Nachricht: Passwort ist 12345!';
$sealedData = '';
$encryptedKeys = [];
$iv = '';

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

if ($result === false) {
    throw new RuntimeException('Versiegelung fehlgeschlagen: ' . openssl_error_string());
}

echo 'Länge der versiegelten Daten: ' . $result . ' Bytes' . PHP_EOL;
echo 'Verschlüsselter Sitzungsschlüssel (Base64): ' . base64_encode($encryptedKeys[0]) . PHP_EOL;
echo 'IV (Base64): ' . base64_encode($iv) . PHP_EOL;

// Zum Übertragen alles Base64-kodieren
$payload = [
    'sealed'   => base64_encode($sealedData),
    'env_key'  => base64_encode($encryptedKeys[0]),
    'iv'       => base64_encode($iv),
];

// Entschlüsseln mit openssl_open()
$decrypted = '';
openssl_open(
    base64_decode($payload['sealed']),
    $decrypted,
    base64_decode($payload['env_key']),
    $keyPair,
    'AES-256-CBC',
    base64_decode($payload['iv'])
);

echo 'Entschlüsselt: ' . $decrypted . PHP_EOL;
Länge der versiegelten Daten: 48 Bytes Verschlüsselter Sitzungsschlüssel (Base64): <RSA-verschlüsselter Base64-String> IV (Base64): <16-Byte-IV als Base64> Entschlüsselt: Geheime Nachricht: Passwort ist 12345!

Nachricht für mehrere Empfänger versiegeln

<?php
// Zwei Schlüsselpaare simulieren (z. B. Empfänger A und B)
function generateKeyPair(): array {
    $kp = openssl_pkey_new(['private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA]);
    $details = openssl_pkey_get_details($kp);
    return [
        'private' => $kp,
        'public'  => openssl_pkey_get_public($details['key']),
    ];
}

$recipientA = generateKeyPair();
$recipientB = generateKeyPair();

$plaintext = 'Vertrauliche Mitteilung an alle Empfänger';
$sealedData = '';
$encryptedKeys = [];
$iv = '';

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

// Empfänger A entschlüsselt
$decryptedA = '';
openssl_open($sealedData, $decryptedA, $encryptedKeys[0], $recipientA['private'], 'AES-256-CBC', $iv);
echo 'Empfänger A liest: ' . $decryptedA . PHP_EOL;

// Empfänger B entschlüsselt
$decryptedB = '';
openssl_open($sealedData, $decryptedB, $encryptedKeys[1], $recipientB['private'], 'AES-256-CBC', $iv);
echo 'Empfänger B liest: ' . $decryptedB . PHP_EOL;
Empfänger A liest: Vertrauliche Mitteilung an alle Empfänger Empfänger B liest: Vertrauliche Mitteilung an alle Empfänger

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Verwende niemals den veralteten Algorithmus RC4 (ehemaliger Standard vor PHP 8.0). Er gilt als kryptografisch gebrochen. Setze immer explizit einen sicheren Algorithmus wie AES-256-CBC.
  • Der Initialisierungsvektor ($iv) ist kein Geheimnis, muss jedoch zusammen mit den versiegelten Daten gespeichert und beim Entschlüsseln übergeben werden. Fehlt er, ist eine Entschlüsselung nicht möglich.
  • Ab PHP 8.0 ist $cipher_algo ein Pflichtparameter und der Typ der Schlüssel wurde von Resource auf OpenSSLAsymmetricKey geändert.
  • Die Funktion unterstützt ausschließlich RSA-Schlüssel für die Versiegelung der Sitzungsschlüssel. Andere Schlüsseltypen (z. B. EC) werden nicht unterstützt.
  • Für neue Implementierungen sollte erwogen werden, ob sodium_crypto_box() oder moderne Bibliotheken wie libsodium besser geeignet sind, da diese eine einfachere und sicherere API bieten.