Signatur
Beschreibung
openssl_cms_encrypt liest den Klartext aus einer Eingabedatei, verschlüsselt ihn mit dem (den) angegebenen X.509-Empfänger-Zertifikat(en) und schreibt die verschlüsselte CMS-Nachricht (Cryptographic Message Syntax, RFC 5652) in eine Ausgabedatei. Die Funktion ist der direkte Nachfolger von openssl_pkcs7_encrypt und arbeitet auf Basis des modernen CMS-Standards statt des älteren PKCS#7-Formats.
Das Verschlüsselungsverfahren basiert auf einem hybriden Ansatz: Der eigentliche Nachrichteninhalt wird symmetrisch verschlüsselt (Standard: AES-128-CBC), der symmetrische Sitzungsschlüssel wird anschließend mit dem öffentlichen Schlüssel jedes Empfänger-Zertifikats asymmetrisch verschlüsselt und in die CMS-Hülle eingebettet. Nur Besitzer des jeweiligen privaten Schlüssels können die Nachricht entschlüsseln.
Der Parameter $certificate akzeptiert ein einzelnes Zertifikat oder ein Array von Zertifikaten, sodass dieselbe Nachricht für mehrere Empfänger gleichzeitig verschlüsselt werden kann. Über $flags lassen sich optionale Verhaltensmodi steuern (z. B. OPENSSL_CMS_DETACHED), und mit $encoding wird das Ausgabeformat (S/MIME, DER oder PEM) gewählt.
Typische Anwendungsfälle sind sichere E-Mail-Kommunikation (S/MIME), verschlüsselte Dateiübertragung und Dokumentenarchivierung, bei der nur autorisierte Empfänger den Inhalt lesen dürfen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $input_filename Pflicht | string | Pfad zur Quelldatei, die den zu verschlüsselnden Klartext enthält. | |
| $output_filename Pflicht | string | Pfad zur Ausgabedatei, in die die verschlüsselte CMS-Nachricht geschrieben wird. Die Datei wird erstellt oder überschrieben. | |
| $certificate Pflicht | array|OpenSSLCertificate|string | Ein oder mehrere X.509-Empfänger-Zertifikate als OpenSSLCertificate-Objekt, PEM-String oder Array davon. Der öffentliche Schlüssel jedes Zertifikats wird verwendet, um den Sitzungsschlüssel zu verschlüsseln. |
|
| $headers Pflicht | array|null | null | Assoziatives Array mit MIME-Headern, die der S/MIME-Nachricht vorangestellt werden (z. B. ['To' => 'empfaenger@example.com']). Kann null sein, wenn keine Header benötigt werden. |
| $flags | int | 0 | Bitmaske aus OPENSSL_CMS_*-Konstanten, z. B. OPENSSL_CMS_BINARY für binäre Inhalte. Standard ist 0. |
| $encoding | int | OPENSSL_ENCODING_SMIME | Kodierungsformat der Ausgabe: OPENSSL_ENCODING_SMIME (Standard, S/MIME), OPENSSL_ENCODING_DER (binäres DER) oder OPENSSL_ENCODING_PEM (Base64-codiertes PEM). |
| $cipher_algo | int | OPENSSL_CIPHER_AES_128_CBC | Symmetrischer Verschlüsselungsalgorithmus für den Nachrichteninhalt, z. B. OPENSSL_CIPHER_AES_256_CBC für stärkere Verschlüsselung. |
Rückgabewert
true zurück, wenn die Verschlüsselung erfolgreich war und die Ausgabedatei geschrieben wurde. Bei einem Fehler (ungültiges Zertifikat, nicht schreibbare Ausgabedatei usw.) wird false zurückgegeben.Beispiele
Einfache CMS-Verschlüsselung für einen Empfänger
<?php
// Empfänger-Zertifikat laden (PEM-Datei)
$cert = openssl_x509_read(file_get_contents('/pfad/zum/empfaenger.pem'));
if (!$cert) {
die('Zertifikat konnte nicht geladen werden: ' . openssl_error_string());
}
$klartext = '/tmp/nachricht.txt';
$verschluesselt = '/tmp/nachricht.cms';
file_put_contents($klartext, 'Geheime Nachricht für den Empfänger.');
$headers = [
'To' => 'empfaenger@example.com',
'From' => 'absender@example.com',
'Subject' => 'Verschlüsselte Nachricht',
];
$result = openssl_cms_encrypt(
$klartext,
$verschluesselt,
$cert,
$headers,
0,
OPENSSL_ENCODING_SMIME,
OPENSSL_CIPHER_AES_256_CBC
);
if ($result) {
echo 'Nachricht erfolgreich verschlüsselt.' . PHP_EOL;
echo file_get_contents($verschluesselt);
} else {
echo 'Fehler: ' . openssl_error_string();
}
CMS-Verschlüsselung für mehrere Empfänger (DER-Format)
<?php
// Zertifikate mehrerer Empfänger laden
$certPaths = [
'/pfad/zu/empfaenger1.pem',
'/pfad/zu/empfaenger2.pem',
];
$certs = array_map(fn($p) => openssl_x509_read(file_get_contents($p)), $certPaths);
foreach ($certs as $c) {
if (!$c) {
die('Mindestens ein Zertifikat ist ungültig: ' . openssl_error_string());
}
}
$eingabe = '/tmp/dokument.txt';
$ausgabe = '/tmp/dokument.der';
file_put_contents($eingabe, 'Vertrauliche Daten für beide Empfänger.');
$ok = openssl_cms_encrypt(
$eingabe,
$ausgabe,
$certs, // Array mit mehreren Zertifikaten
null, // keine MIME-Header (reines DER)
0,
OPENSSL_ENCODING_DER,
OPENSSL_CIPHER_AES_256_CBC
);
echo $ok
? 'DER-verschlüsselte Datei erstellt, Größe: ' . filesize($ausgabe) . ' Bytes'
: 'Fehler: ' . openssl_error_string();
// Wichtig · Fallstricke
Sicherheitshinweise:
- Verwende mindestens
OPENSSL_CIPHER_AES_128_CBC; ältere Algorithmen wieOPENSSL_CIPHER_DESoderOPENSSL_CIPHER_RC2_40gelten als unsicher und sollten vermieden werden. - Die Stärke der Verschlüsselung hängt auch vom verwendeten Zertifikat ab – RSA-Schlüssel sollten mindestens 2048 Bit, besser 4096 Bit groß sein.
- Temporäre Klartextdateien sollten nach erfolgreicher Verschlüsselung sicher gelöscht werden (z. B. mit
unlink), da sie sensible Daten enthalten können. - Diese Funktion ersetzt
openssl_pkcs7_encryptfür neue Implementierungen; beide erzeugen kompatible S/MIME-Nachrichten, CMS ist jedoch der aktuellere Standard. - Eingabe- und Ausgabepfad müssen für den PHP-Prozess les- bzw. schreibbar sein; Fehler werden über
openssl_error_string()abgerufen.