¿Por qué PKCS#12?
JKS es un formato que solo entiende Java. PKCS#12 (extensión .p12 o .pfx) es un estándar que también leen OpenSSL, Windows, las herramientas de servidores web y los navegadores. Por eso keytool crea PKCS#12 por defecto desde Java 9. Con archivos JKS aparece el aviso:
Warning: The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore ..."
El comando
keytool -importkeystore \ -srckeystore keystore.jks -srcstoretype JKS \ -destkeystore keystore.p12 -deststoretype PKCS12
keytool pide la contraseña del origen y la nueva contraseña. Se copian todas las entradas: claves con su cadena y certificados de confianza. Después ajusta nombre y tipo en la aplicación, por ejemplo en Spring Boot:
server.ssl.key-store=classpath:keystore.p12 server.ssl.key-store-type=PKCS12
La trampa de las contraseñas
En JKS cada clave puede tener su propia contraseña, distinta de la del keystore. keytool no lo admite en PKCS#12: la contraseña de la clave y la del almacén son la misma. keytool muestra entonces:
Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -destkeypass value.
Si la clave tenía otra contraseña, indícala con -srckeypass. En el resultado solo vale la contraseña del almacén. Quita en la aplicación un ajuste key-password separado o ponle el mismo valor.
Volver a JKS
Algunas aplicaciones o appliances antiguos exigen JKS. El camino de vuelta es el mismo comando con los tipos intercambiados:
keytool -importkeystore \ -srckeystore keystore.p12 -srcstoretype PKCS12 \ -destkeystore keystore.jks -deststoretype JKS
PKCS#12 a PEM para nginx o Apache
Para un servidor web o un balanceador de carga normalmente necesitas PEM. Con OpenSSL o con el conversor de certificados:
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
Java antiguo y OpenSSL 3
El cifrado interno de PKCS#12 ha cambiado. Java 12 y posteriores (y también Java 8u301 y 11.0.12) escriben PKCS#12 con AES-256 y SHA-256. Las versiones anteriores usaban RC2 y 3DES. Eso causa dos problemas:
- Un Java antiguo no lee archivos nuevos. Solución: pasar
-J-Dkeystore.pkcs12.legacya keytool al crearlo. keytool escribe entonces el formato antiguo. - OpenSSL 3 no lee archivos antiguos y muestra
unsupportedoRC2-40-CBC. Solución:openssl pkcs12 -legacy …o reescribir el archivo con un keytool actual.
El asistente de keystores Java lee ambas variantes y al guardar te deja elegir «moderno» (AES-256) o «compatible» (3DES).
FAQ
¿Pierdo algo en la conversión?
Se copian claves, cadenas y certificados de confianza. Solo se pierden las contraseñas distintas por clave, porque PKCS#12 en Java usa una única contraseña.
¿Puedo renombrar sin más el .p12 a .pfx?
Sí. Es el mismo formato; Windows suele esperar la extensión .pfx.
¿Y JCEKS?
JCEKS también puede guardar claves simétricas. keytool las pasa igualmente a PKCS#12 si indicas -srcstoretype JCEKS.
¿Tengo que convertir también los truststores?
No necesariamente; Java sigue leyendo JKS. El cacerts del JDK es PKCS#12 desde Java 9, pero se lee sea cual sea su tipo.