Die Frage PKCS#12 vs. PEM stellt sich immer dann, wenn ein Schlüssel und ein Zertifikat zwischen Unix-Servern und Plattformen mit eigenen Schlüsselspeichern wandern. PEM-Dateien bestehen aus getrennten, lesbaren Blöcken, die Software auf Basis von OpenSSL direkt lädt; eine PKCS#12-Datei (.p12 oder .pfx) ist ein einziger verschlüsselter Container, den Betriebssysteme und Java in einem Schritt importieren. Dieselben Schlüssel und Zertifikate, eine andere Verpackung – und die Algorithmen der Verpackung entscheiden, ob ein Import gelingt.
Auf einen Blick
| PEM | PKCS#12 (PFX) | |
|---|---|---|
| Spezifikation | RFC 7468 (Textkodierung von DER) | RFC 7292 (PKCS #12 v1.1), RFC 9579 (PBMAC1) |
| Format | Text, ein oder mehrere Blöcke BEGIN … END | Binärer DER-Container aus „Safe Bags“ |
| Enthält | Was immer du in die Datei schreibst: Schlüssel, Zertifikate, CRLs | Private Schlüssel, Zertifikate, CRLs, Secrets, mit Anzeigenamen und Schlüssel-IDs |
| Schutz | Optional pro Schlüssel (verschlüsseltes PKCS#8) | Passwortbasierte Verschlüsselung der Bags plus ein Integritäts-MAC |
| Standardschutz in OpenSSL 3.6 | PBES2 mit AES-256-CBC für verschlüsselte Schlüssel | PBES2, PBKDF2-HMAC-SHA256, AES-256-CBC, 2.048 Iterationen; HMAC-SHA256-MAC |
OpenSSL -legacy | Nicht anwendbar | RC2-40 für Zertifikate, 3DES für Schlüssel, HMAC-SHA1-MAC |
| Übliche Dateiendungen | .pem, .crt, .key | .p12, .pfx |
| Verwendet von | OpenSSL, Webservern, Proxys, Go, Python, Node.js | Windows-Zertifikatsspeicher, macOS-Schlüsselbund, Java KeyStore, Browsern, signtool |
Was in einer .pfx steckt
Eine PKCS#12-Datei ist eine Struktur PFX: ein Authenticated Safe aus Inhaltsblöcken, die jeweils Bags enthalten. Private Schlüssel liegen in Einträgen vom Typ pkcs8ShroudedKeyBag (verschlüsseltes PKCS#8), Zertifikate in Einträgen vom Typ certBag (oft ebenfalls in einem verschlüsselten Block), und Bags tragen Attribute wie friendlyName und localKeyId, die einen Schlüssel seinem Zertifikat zuordnen. Ein aus dem Passwort abgeleiteter MAC schützt die Integrität der gesamten Datei; RFC 9579 (2024) ergänzt PBMAC1, das den MAC-Schlüssel mit PBKDF2 statt mit der veralteten KDF von PKCS#12 ableitet.
PEM hat keinen Container: Ein Server wird mit einer Schlüsseldatei und einer Datei für das Zertifikat (oder die Kette) konfiguriert oder mit einer einzigen Datei mit mehreren Blöcken. Der Schutz hängt allein an der Schlüsseldatei – auf Servern ist sie meist gar nicht geschützt, weil der Prozess den Schlüssel lesen muss, ohne dass jemand ein Passwort eintippt.
Konvertieren
Das folgende Skript, ausgeführt mit OpenSSL 3.6.5, packt einen Wegwerf-Schlüssel und ein Wegwerf-Zertifikat in eine PKCS#12-Datei und entpackt sie wieder.
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
openssl req -new -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout key.pem \
-subj "/CN=example.com" -days 30 -out cert.pem 2>/dev/null
openssl pkcs12 -export -inkey key.pem -in cert.pem -name demo -passout pass:demo -out bundle.p12
openssl pkcs12 -in bundle.p12 -passin pass:demo -info -noout 2>&1 | grep -E "MAC:|Shrouded|PKCS7 Encrypted"
openssl pkcs12 -in bundle.p12 -passin pass:demo -nodes -out extracted.pem 2>/dev/null
grep -E "^-----BEGIN" extracted.pem
cd / && rm -rf "$dir"
MAC: sha256, Iteration 2048
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
-----BEGIN CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
Zwischenzertifikate nimmst du mit -certfile chain.pem auf; um nur die Zertifikate zu extrahieren, verwende -nokeys, für den Schlüssel allein -nocerts. Das Flag -nodes (in neueren Releases -noenc) schreibt den Schlüssel unverschlüsselt, behandle die Ausgabe also entsprechend.
Kompatibilität: moderne vs. veraltete Algorithmen
OpenSSL 3.0 hat die Voreinstellungen für den Export von RC2-40 und 3DES mit einem HMAC-SHA1-MAC auf AES-256 mit einem HMAC-SHA256-MAC umgestellt. Viele Programme, die solche Dateien lesen, zogen erst später nach:
- macOS: Das Security-Framework von Apple importiert moderne PKCS#12-Dateien ab macOS 15; macOS 14 und älter scheitern mit „MAC verification failed during PKCS12 import (wrong password?)“, selbst mit dem richtigen Passwort.
- Java: JDK 9 hat PKCS#12 zum Standardtyp für Keystores gemacht; JDK 16 (und Updates von 8 und 11 aus dem Jahr 2021) hat die eigene Voreinstellung von Java auf PBES2 mit AES-256 und einem HMAC-SHA256-MAC umgestellt, und aktuelle Versionen lesen Dateien von OpenSSL 3.
- Windows: Aktuelle Releases importieren PFX-Dateien mit AES-256; sehr alte Versionen von Windows Server brauchen möglicherweise die Legacy-Form.
- OpenSSL 3 beim Lesen alter Dateien: Dateien, deren Zertifikate mit RC2-40 verschlüsselt sind (der Standard von OpenSSL 1.1 und das, was Exporte mit
-legacyverwenden, wenn RC2 einkompiliert ist), lassen sich nur mit-legacyladen, das den Legacy-Provider lädt. Ohne ihn gibt OpenSSL 3.6.5 fürRC2-40-CBCdie Meldungerror:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupportedaus, und Node.js 26 lehnt die Datei mitUnsupported PKCS12 PFX dataab. Dateien, die nur 3DES und einen HMAC-SHA1-MAC verwenden, lassen sich ohne den Legacy-Provider laden.
Wenn eine moderne Datei auf einem bekanntermaßen alten Ziel scheitert, exportiere mit openssl pkcs12 -export -legacy … oder wähle die Algorithmen explizit (-keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -macalg SHA1), und behandle diese Datei bei der Übertragung als schwach geschützt.
Die Fehlermeldungen führen hier in die Irre: „MAC verification failed“ oder „wrong password“ bedeutet meist, dass das lesende Programm den MAC- oder Verschlüsselungsalgorithmus nicht unterstützt, und nicht, dass das Passwort falsch ist. Untersuche die Datei mit openssl pkcs12 -info -noout (bei alten Dateien mit -legacy), um zu sehen, welche Algorithmen verwendet wurden, bevor du Passwörter rätst.
PKCS#12 als Keystore
Java behandelt eine PKCS#12-Datei als Keystore: keytool -list -keystore bundle.p12 -storetype PKCS12 zeigt ihre Einträge, und der friendlyName wird zum Alias. Ein Keystore kann mehrere Schlüsseleinträge und vertrauenswürdige Zertifikate enthalten, was eine PEM-Datei ohne Namenskonventionen nicht ausdrücken kann. Truststores sind ein Sonderfall: Ein PKCS#12-Truststore, der nur Zertifikate enthält, braucht Java-spezifische Attribute, die die Zertifikate als vertrauenswürdig markieren; deshalb ist keytool -importcert der zuverlässige Weg, einen solchen Truststore zu erstellen. Die meisten anderen Plattformen ignorieren diese Java-Attribute und ordnen Schlüssel und Zertifikate beim Import über übereinstimmende Werte von localKeyId einander zu.
Wann welches Format passt
- TLS auf Linux-Servern, Reverse Proxys, Kubernetes-Ingress: Schlüssel in PEM und Zertifikat mit vollständiger Kette.
- Zertifikatsimporte in Windows IIS, Azure App Service und Key Vault: PKCS#12.
- TLS mit Java und Spring Boot: ein PKCS#12-Keystore (oder PEM, das neuere Versionen von Spring Boot direkt akzeptieren).
- Client-Zertifikate für Browser und Mobilgeräte: PKCS#12 mit einem starken Passwort, getrennt vom Passwort zugestellt.
- Codesignatur mit signtool oder jarsigner: PKCS#12, sofern der Schlüssel überhaupt in einer Datei liegt; öffentlich vertrauenswürdige Signaturschlüssel für die Codesignatur müssen seit 2023 in Hardware liegen.
- Untersuchung und Debugging: PEM oder der PFX-Inspektor, der Bags und Algorithmen lokal auflistet, ohne den Schlüssel offenzulegen.
Hinweise zur Migration
- Nimm die vollständige Kette auf, wenn du eine PKCS#12-Datei für Server oder Clients erstellst, und zwar mit dem Leaf-Zertifikat zuerst; fehlende Zwischenzertifikate sind der häufigste Fehler nach dem Import.
- Gleiche Schlüssel und Zertifikat ab, bevor du sie verpackst: Der Schlüssel- und Zertifikats-Matcher vergleicht ihre öffentlichen Schlüssel.
- Wähle die Algorithmen für das älteste lesende System und rüste danach auf: Exportiere mit modernen Voreinstellungen neu, sobald die alten Plattformen verschwunden sind.
- Verwende starke, zufällige Passwörter für PKCS#12-Dateien, die verschickt werden, denn die Datei lässt sich offline angreifen; die Zahl von 2.048 PBKDF2-Iterationen, die OpenSSL standardmäßig verwendet, ist gemessen an den Maßstäben der Passwortspeicherung niedrig.
- Lass extrahierte Schlüssel nicht herumliegen: Nachdem du eine
.pfxfür einen Server in PEM konvertiert hast, schränke die Dateiberechtigungen ein und lösche temporäre Kopien.
Quellen
- RFC 7292, PKCS #12 v1.1
- RFC 9579, PBMAC1 in PKCS #12
- RFC 7468, PEM-Kodierungen
- RFC 5958, PKCS #8: Pakete asymmetrischer Schlüssel
- OpenSSL, Handbuchseite zu openssl-pkcs12
- JDK-8228481, stärkere Standardalgorithmen für PKCS #12 in Java
- Apple Developer Forums: Unterstützung für modernes PKCS #12 in macOS 15