Start · Sprachen · PHP · Referenz · openssl_cms_encrypt

openssl_cms_encrypt

Funktion

Verschlüsselt eine Datei als CMS/S/MIME-Nachricht mit dem öffentlichen Schlüssel eines oder mehrerer Empfänger-Zertifikate.

seit PHP 8.0.0 Kategorie: crypto

Signatur

openssl_cms_encrypt(string $input_filename, string $output_filename, array|OpenSSLCertificate|string $certificate, array|null $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, int $cipher_algo = OPENSSL_CIPHER_AES_128_CBC): bool

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

Typ
bool
Beschreibung
Gibt 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();
}
Nachricht erfolgreich verschlüsselt.

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();
DER-verschlüsselte Datei erstellt, Größe: 1234 Bytes

// Wichtig · Fallstricke

Sicherheitshinweise:

  • Verwende mindestens OPENSSL_CIPHER_AES_128_CBC; ältere Algorithmen wie OPENSSL_CIPHER_DES oder OPENSSL_CIPHER_RC2_40 gelten 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_encrypt fü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.