Start · Sprachen · PHP · Referenz · openssl_pkcs7_read

openssl_pkcs7_read

Funktion

Liest eine PKCS#7-Struktur aus einem PEM-kodierten String und exportiert die enthaltenen Zertifikate als Array von PEM-Strings.

seit PHP 5.0.0 Kategorie: crypto

Signatur

openssl_pkcs7_read(string $data, array &$certificates): bool

Beschreibung

openssl_pkcs7_read() analysiert eine PKCS#7-Nachricht (auch als S/MIME-Struktur bekannt), die im PEM-Format vorliegt, und extrahiert alle darin enthaltenen X.509-Zertifikate. Die gefundenen Zertifikate werden als Array von PEM-kodierten Strings in den per Referenz übergebenen Parameter $certificates geschrieben.

Die Funktion ist besonders nützlich, wenn man aus einer signierten oder verschlüsselten S/MIME-E-Mail oder einer PKCS#7-Datei die enthaltenen Zertifikate für eine spätere Verarbeitung – etwa zur Validierung einer Zertifikatskette – extrahieren möchte, ohne eine vollständige PKCS#7-Verifikation durchzuführen.

Der Eingabe-String $data muss eine gültige PEM-kodierte PKCS#7-Struktur enthalten, d. h. er beginnt typischerweise mit -----BEGIN PKCS7-----. DER-kodierte Daten müssen vorher in PEM umgewandelt werden (z. B. mit openssl smime -pk7out oder base64_encode() mit den passenden Headern).

Im Fehlerfall gibt die Funktion false zurück und die OpenSSL-Fehlerwarteschlange enthält weitere Details, die über openssl_error_string() abgerufen werden können.

Parameter

Name Typ Default Beschreibung
$data Pflicht string Eine PEM-kodierte PKCS#7-Struktur als String. Der String muss gültige PEM-Header und -Footer enthalten (-----BEGIN PKCS7----------END PKCS7-----).
$certificates Pflicht array Wird per Referenz übergeben und nach dem Aufruf mit den extrahierten Zertifikaten befüllt. Jedes Element ist ein PEM-kodierter Zertifikats-String (-----BEGIN CERTIFICATE----------END CERTIFICATE-----).

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn die PKCS#7-Struktur erfolgreich gelesen und die Zertifikate extrahiert werden konnten. Bei einem Fehler (z. B. ungültiges PEM-Format oder kein gültiger PKCS#7-Block) wird false zurückgegeben.

Beispiele

Zertifikate aus einer PKCS#7-Datei extrahieren

<?php
// PKCS#7-Datei einlesen (muss PEM-kodiert sein)
$pkcs7Data = file_get_contents('/path/to/signed.p7b');

$certificates = [];
if (openssl_pkcs7_read($pkcs7Data, $certificates)) {
    echo 'Gefundene Zertifikate: ' . count($certificates) . PHP_EOL;
    foreach ($certificates as $index => $cert) {
        echo "--- Zertifikat #{$index} ---" . PHP_EOL;
        echo $cert . PHP_EOL;

        // Zertifikatsdetails auslesen
        $parsed = openssl_x509_parse($cert);
        echo 'Subject CN: ' . ($parsed['subject']['CN'] ?? 'n/a') . PHP_EOL;
    }
} else {
    echo 'Fehler beim Lesen der PKCS#7-Daten: ' . openssl_error_string() . PHP_EOL;
}
Gefundene Zertifikate: 2 --- Zertifikat #0 --- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- Subject CN: example.com --- Zertifikat #1 --- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- Subject CN: Intermediate CA

PKCS#7-Block aus einer S/MIME-E-Mail extrahieren und Zertifikate lesen

<?php
// Simulierter PEM-PKCS#7-Block (z. B. aus einer signierten S/MIME-Mail)
$smimeFile = file_get_contents('/path/to/smime.p7m');

// Mit openssl smime_read_pkcs7 erst den PKCS7-Handle erzeugen,
// oder direkt als PEM-String übergeben, falls bereits PEM vorliegt.

$certs = [];
$result = openssl_pkcs7_read($smimeFile, $certs);

if ($result === false) {
    while ($msg = openssl_error_string()) {
        echo 'OpenSSL-Fehler: ' . $msg . PHP_EOL;
    }
    exit(1);
}

// Alle extrahierten Zertifikate in separate Dateien speichern
foreach ($certs as $i => $pemCert) {
    $filename = "/tmp/extracted_cert_{$i}.pem";
    file_put_contents($filename, $pemCert);
    echo "Zertifikat {$i} gespeichert in: {$filename}" . PHP_EOL;
}
Zertifikat 0 gespeichert in: /tmp/extracted_cert_0.pem Zertifikat 1 gespeichert in: /tmp/extracted_cert_1.pem

// Wichtig · Fallstricke

Format-Hinweis: Die Funktion erwartet ausschließlich PEM-kodierte Eingabedaten. DER-kodierte Binärdaten (.p7b im Binärformat) werden nicht akzeptiert. Zur Konvertierung kann das Kommandozeilenwerkzeug openssl pkcs7 -inform DER -outform PEM -in input.p7b -out output.pem verwendet werden.

Nur Zertifikate: Die Funktion extrahiert lediglich die in der PKCS#7-Struktur enthaltenen Zertifikate, nicht aber die eigentliche Nachricht, Signaturen oder private Schlüssel. Für eine vollständige Verifikation einer signierten Nachricht sollte openssl_pkcs7_verify() verwendet werden.

Sicherheit: Vertrauen Sie extrahierten Zertifikaten nicht blind. Ein extrahiertes Zertifikat muss stets gegen eine vertrauenswürdige Zertifizierungsstelle (CA) validiert werden, bevor es für sicherheitsrelevante Entscheidungen genutzt wird.