JKS in PKCS#12 umwandeln – und zurück

Seit Java 9 ist PKCS#12 das Standardformat für Keystores, und keytool mahnt bei jedem Zugriff auf eine JKS-Datei zur Migration. Die Umwandlung ist ein Befehl, die Stolperfallen liegen bei Kennwörtern und alten Versionen.

Warum PKCS#12?

JKS ist ein Format, das nur Java versteht. PKCS#12 (Endung .p12 oder .pfx) ist ein Standard, den auch OpenSSL, Windows, nginx-Werkzeuge und Browser lesen. Seit Java 9 erzeugt keytool deshalb standardmäßig PKCS#12. Bei JKS-Dateien erscheint die Warnung:

Warning: The JKS keystore uses a proprietary format. It is recommended to migrate
to PKCS12 which is an industry standard format using "keytool -importkeystore ..."

Der Befehl

keytool -importkeystore \
  -srckeystore keystore.jks -srcstoretype JKS \
  -destkeystore keystore.p12 -deststoretype PKCS12

keytool fragt nach dem Kennwort der Quelle und dem neuen Kennwort. Alle Einträge werden übernommen: Schlüssel mit Zertifikatskette und vertrauenswürdige Zertifikate. Danach in der Anwendung Dateiname und Typ anpassen, zum Beispiel in Spring Boot:

server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-type=PKCS12

Die Kennwort-Falle

In JKS kann jeder Schlüssel ein eigenes Kennwort haben, das sich vom Keystore-Kennwort unterscheidet. PKCS#12 kennt das in keytool nicht: Schlüssel- und Store-Kennwort sind gleich. keytool meldet dann:

Warning: Different store and key passwords not supported for PKCS12 KeyStores.
Ignoring user-specified -destkeypass value.

Hatte der Schlüssel ein anderes Kennwort, gib es mit -srckeypass an. Im Ergebnis gilt nur noch das Store-Kennwort. Entferne in der Anwendung eine separate key-password-Einstellung oder setz sie auf denselben Wert.

Zurück nach JKS

Manche alten Anwendungen oder Appliances verlangen JKS. Der Weg zurück ist derselbe Befehl mit vertauschten Typen:

keytool -importkeystore \
  -srckeystore keystore.p12 -srcstoretype PKCS12 \
  -destkeystore keystore.jks -deststoretype JKS

PKCS#12 in PEM für nginx oder Apache

Soll das Zertifikat auf einen Webserver oder Load Balancer, brauchst du meist PEM. Das geht mit OpenSSL oder im Zertifikat-Konverter:

openssl pkcs12 -in keystore.p12 -clcerts -nokeys -out server.crt
openssl pkcs12 -in keystore.p12 -cacerts -nokeys -out chain.crt
openssl pkcs12 -in keystore.p12 -nocerts -nodes -out server.key

Alte Java-Versionen und OpenSSL 3

Die Verschlüsselung innerhalb von PKCS#12 hat sich geändert. Java 12 und neuer (sowie Java 8u301 und 11.0.12) schreiben PKCS#12 mit AES-256 und SHA-256. Ältere Java-Versionen nutzten RC2 und 3DES. Daraus ergeben sich zwei Probleme:

Der Java-Keystore-Helfer liest beide Varianten und lässt dich beim Speichern zwischen „modern“ (AES-256) und „kompatibel“ (3DES) wählen.

FAQ

Verliere ich bei der Umwandlung etwas?

Schlüssel, Ketten und vertrauenswürdige Zertifikate werden übernommen. Nur unterschiedliche Kennwörter je Schlüssel gehen verloren, weil PKCS#12 in Java ein gemeinsames Kennwort nutzt.

Kann ich die .p12 einfach in .pfx umbenennen?

Ja. Beides ist dasselbe Format, Windows erwartet meist die Endung .pfx.

Was ist mit JCEKS?

JCEKS kann zusätzlich symmetrische Schlüssel speichern. keytool überträgt sie ebenfalls nach PKCS#12, wenn du -srcstoretype JCEKS angibst.

Muss ich Truststores auch umwandeln?

Nicht zwingend, Java liest JKS weiterhin. Das cacerts des JDK ist seit Java 9 selbst schon PKCS#12, wird aber unabhängig vom Typ gelesen.