Pourquoi PKCS#12 ?
JKS est un format que seul Java comprend. PKCS#12 (extension .p12 ou .pfx) est un standard lu aussi par OpenSSL, Windows, les outils des serveurs web et les navigateurs. Depuis Java 9, keytool crée donc du PKCS#12 par défaut. Pour un fichier JKS, il affiche :
Warning: The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore ..."
La commande
keytool -importkeystore \ -srckeystore keystore.jks -srcstoretype JKS \ -destkeystore keystore.p12 -deststoretype PKCS12
keytool demande le mot de passe de la source et le nouveau mot de passe. Toutes les entrées sont reprises : clés avec leur chaîne et certificats de confiance. Adapte ensuite le nom et le type dans l’application, par exemple dans Spring Boot :
server.ssl.key-store=classpath:keystore.p12 server.ssl.key-store-type=PKCS12
Le piège des mots de passe
En JKS, chaque clé peut avoir son propre mot de passe, différent de celui du keystore. keytool ne le permet pas en PKCS#12 : mot de passe de la clé et du magasin sont identiques. keytool affiche alors :
Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -destkeypass value.
Si la clé avait un autre mot de passe, indique-le avec -srckeypass. Au final, seul le mot de passe du magasin compte. Supprime dans l’application un réglage key-password séparé ou donne-lui la même valeur.
Revenir à JKS
Certaines anciennes applications ou appliances exigent JKS. Le retour se fait avec la même commande en inversant les types :
keytool -importkeystore \ -srckeystore keystore.p12 -srcstoretype PKCS12 \ -destkeystore keystore.jks -deststoretype JKS
PKCS#12 en PEM pour nginx ou Apache
Pour un serveur web ou un répartiteur de charge, il faut en général du PEM. Avec OpenSSL ou le convertisseur de certificats :
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
Anciennes versions de Java et OpenSSL 3
Le chiffrement interne de PKCS#12 a changé. Java 12 et plus (ainsi que Java 8u301 et 11.0.12) écrivent le PKCS#12 en AES-256 et SHA-256. Les versions plus anciennes utilisaient RC2 et 3DES. D’où deux problèmes :
- Un vieux Java ne lit pas les nouveaux fichiers. Solution : passer
-J-Dkeystore.pkcs12.legacyà keytool lors de la création. keytool écrit alors l’ancien format. - OpenSSL 3 ne lit pas les anciens fichiers et signale
unsupportedouRC2-40-CBC. Solution :openssl pkcs12 -legacy …ou réécrire le fichier avec un keytool récent.
L’assistant keystore Java lit les deux variantes et te laisse choisir « moderne » (AES-256) ou « compatible » (3DES) à l’enregistrement.
FAQ
Est-ce que je perds quelque chose à la conversion ?
Clés, chaînes et certificats de confiance sont repris. Seuls les mots de passe différents par clé disparaissent, car PKCS#12 utilise un mot de passe unique en Java.
Puis-je simplement renommer le .p12 en .pfx ?
Oui. C’est le même format ; Windows attend en général l’extension .pfx.
Et JCEKS ?
JCEKS peut aussi stocker des clés symétriques. keytool les transfère aussi en PKCS#12 si tu indiques -srcstoretype JCEKS.
Faut-il aussi convertir les truststores ?
Pas obligatoirement, Java lit toujours JKS. Le cacerts du JDK est lui-même en PKCS#12 depuis Java 9, mais il est lu quel que soit son type.