Estoy escribiendo una aplicación Java 8 y quiero configurar un almacén de claves y un almacén de confianza simples mediante un certificado autofirmado.
Normalmente esto va de la siguiente manera:
openssl .keytool Ahora me gustaría usar solo openssl y crear almacenes de claves .p12 en lugar de almacenes de claves .jks.
La creación de un almacén de claves .p12 funciona muy bien con los siguientes comandos:
# Create private key and certificate openssl req -x509 -newkey rsa:"${rsa}" -sha256 \ -keyout "${key}" \ -out "${cert}" \ -days "${days}" # Create .p12 keystore openssl pkcs12 -export -in "${cert}" -inkey "${key}" -out "${keystore}"Este almacén de claves parece estar funcionando correctamente, ya que proporcionar un archivo de confianza .jks correspondiente en mi aplicación Java hará que la conexión TLS funcione. Sin embargo, no puedo hacer funcionar un almacén de confianza .p12.
Intenté crear el almacén de confianza como se sugiere aquí :
# Create .p12 truststore openssl pkcs12 -export -nokeys -in "${cert}" -out "${truststore}"y luego cargarlo así:
FileInputStream fis = new FileInputStream(new File(trustorePath)); KeyStore trustStore = KeyStore.getInstance("PKCS12"); trustStore.load(fis, truststorePassword.toCharArray()); fis.close();pero recibo la siguiente excepción en mi código Java:
Error inesperado: java.security.InvalidAlgorithmParameterException: el parámetro trustAnchors no debe estar vacío
¿Alguna idea de lo que estoy haciendo mal?
(Se agradecería mucho un fragmento funcional que use .p12 truststore con Java 8).
Una posible explicación para este comportamiento:
El proveedor estándar PKCS#12 hasta Java 7 no permitía ninguna entrada de certificado de confianza. La Guía de referencia de JSSE dice esto:
No se admite el almacenamiento de certificados de confianza en un almacén de claves PKCS12. PKCS12 se utiliza principalmente para entregar claves privadas con las cadenas de certificados asociadas. No tiene ninguna noción de certificados "de confianza". En términos de interoperabilidad, otros proveedores de PKCS12 tienen la misma restricción. Los navegadores como Mozilla e Internet Explorer no aceptan un archivo PKCS12 solo con certificados de confianza.
Esto ha cambiado un poco en Java 8, que admite certificados de confianza en PKCS#12, si están marcados con un atributo especial (OID 2.16.840.1.113894.746875.1.1):
openssl pkcs12 -in microsoft.p12 -info MAC Iteration 1024 MAC verified OK PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 1024 Certificate bag Bag Attributes friendlyName: microsoft it ssl sha2 (baltimore cybertrust root) 2.16.840.1.113894.746875.1.1: <Unsupported tag 6>
Fuente:
No he encontrado la manera de hacerlo con openssl, aunque encontré la manera de hacerlo con keytool (una parte de la suite OpenJDK).
Necesitaba crear un almacén de claves que contuviera el certificado de CA con el 2.16.840.1.113894.746875.1.1: <Unsupported tag 6> y un certificado adicional y su clave sin este atributo. Me gustaría compartir la solución con otras personas que encontrarán esta página buscando en Google openssl "2.16.840.1.113894.746875.1.1" :-)
Este comando crea un PKCS12 con el certificado de CA (suponiendo que ya tenga una CA) que tiene el 2.16.840.1.113894.746875.1.1: <Unsupported tag 6> :
keytool -storepass '***' -import -alias ca -file ***/ca.crt.pem -keystore ***/ca.p12 -deststoretype PKCS12Este comando convierte el certificado adicional con codificación PEM y su clave privada en PKCS12:
openssl pkcs12 -in ***/additional.cert.pem -inkey ***/additional.key.pem -name additional -export -out ***/additional.p12Este comando fusiona el almacén de claves PKCS12 que contiene el certificado de CA con el almacén de claves PKCS12 que contiene la clave adicional y su clave privada:
keytool -importkeystore -srckeystore ***/ca.p12 -srcstoretype pkcs12 -srcstorepass '***' -destkeystore ***/additional.p12 -deststoretype pkcs12 -deststorepass '***'