openssl - recomienda - keytool commands
Convertir almacén de claves JKS firmado por CA a PEM (3)
No estoy seguro de que sea posible extraer la cadena con keytool
pero se puede hacer con un pequeño programa de Java:
public void extract(KeyStore ks, String alias, char[] password, File dstdir) throws Exception
{
KeyStore.PasswordProtection pwd = new KeyStore.PasswordProtection(password);
KeyStore.PrivateKeyEntry entry = (KeyStore.PasswordKeyEntry)ks.getEntry(alias, pwd);
Certificate[] chain = entry.getCertificateChain();
for (int i = 0; i < chain.length; i++) {
Certificate c = chain[i];
FileOutputStream out = new FileOutputStream(new File(dstdir, String.format("%s.%d.crt", alias, i)));
out.write(c.getEncoded());
out.close();
}
}
Este código debe escribir todos los certificados de la cadena en formato DER en el directorio enviado.
Tengo un almacén de claves JKS con certificado firmado por CA. Necesito exportarlo en formato PEM para usarlo con nginx. Necesito hacerlo de tal manera que incluya toda la cadena, para que mi cliente pueda verificar la firma.
Si hago algo como:
keytool -exportcert -keystore mykestore.jks -file mycert.crt -alias myalias
openssl x509 -out mycert.crt.pem -outform pem -in mycert.crt -inform der
Solo incluye el certificado de nivel más bajo. La verificación falla:
$ openssl s_client -connect localhost:443
CONNECTED(00000003)
depth=0 /O=*.mydomain.com/OU=Domain Control Validated/CN=*.mydomain.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /O=*.mydomain.com/OU=Domain Control Validated/CN=*.mydomain.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 /O=*.mydomain.com/OU=Domain Control Validated/CN=*.mydomain.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/O=*.mydomain.com/OU=Domain Control Validated/CN=*.mydomain.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=123123
... (only one certificate!)
...
SSL-Session:
...
Verify return code: 21 (unable to verify the first certificate)
De Java:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Mientras que Jetty con el mismo almacén de claves JKS imprime lo siguiente:
$ openssl s_client -connect localhost:8084
CONNECTED(00000003)
depth=2 /C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/O=*.mydomain.com/OU=Domain Control Validated/CN=*.mydomain.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=1234
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=1234
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
2 s:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...
SSL-Session:
Verify return code: 19 (self signed certificate in certificate chain)
Aunque openssl devuelve ese 19 error, ya no es un problema para Java HttpsURLConnection
y eso es todo lo que me importa.
Entonces, ¿cómo puedo exportar toda la cadena de JKS en un formato (por ejemplo, PEM) que funciona tanto con el servidor nginx como con el cliente de Java? ¿Qué me estoy perdiendo?
Usted puede convertir fácilmente un archivo JKS en un archivo PKCS12:
keytool -importkeystore -srckeystore keystore.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore keystore.p12
A continuación, puede extraer la clave privada y cualquier cert con:
openssl pkcs12 -in keystore.p12
Un problema bastante grande que encuentro con frecuencia es que, al generar el CSR para obtener nuestro certificado, el almacén de claves (el almacén de claves jks formateado con el Sol) no genera la clave .key ni proporciona ninguna posibilidad para obtener el .key. Así que siempre terminé con un .pem / .crt sin forma de usarlo con Apache2, que no puede leer un almacén de claves JKS como Tomcat, pero en su lugar requiere un par .key + .pem / .crt sin empaquetar.
Para comenzar, obtenga una "copia" de su almacén de claves existente y salte al quinto comando a continuación, o cree uno propio como este:
C:/Temp>keytool -genkey -alias tomcat -keyalg RSA -keystore
keystore.jks -keysize 2048 -validity 730 -storepass changeit
Luego, de forma opcional, cree una CSR de 2 años y luego importe la respuesta de CSR, en el siguiente proceso de 3 pasos:
C:/Temp>keytool -certreq -alias mydomain -keystore keystore.jks
-file mydomain.csr
C:/Temp>keytool -import -trustcacerts -alias root -file
RootPack.crt -keystore keystore.jks -storepass changeit
C:/Temp>keytool -import -trustcacerts -alias tomcat -file mydomain.response.crt
-keystore keystore.jks -storepass changeit
Para que esto funcione, y si ya tiene su archivo de almacén de claves JKS que usa para un servidor de aplicaciones Tomcat, siga los siguientes pasos:
Primero, obtenga el certificado formateado DER (binario) en un archivo llamado "exported-der.crt":
C:/Temp>keytool -export -alias tomcat -keystore keystore.jks -file
exported-der.crt
Luego, ver y verificarlo:
C:/Temp>openssl x509 -noout -text -in exported-der.crt -inform der
Ahora querrá convertirlo a formato PEM, que se usa más ampliamente en aplicaciones como Apache y OpenSSL para realizar la conversión PKCS12:
C:/Temp>openssl x509 -in exported-der.crt -out exported-pem.crt
-outform pem -inform der
A continuación, descargue y use ExportPriv para obtener la clave privada no encriptada de su almacén de claves:
C:/Temp>java ExportPriv <keystore> <alias> <password> > exported-pkcs8.key
A estas alturas probablemente se dé cuenta de que la clave privada se está exportando como formato PKCS # 8 PEM. Para obtener el formato RSA que funciona con Apache (PKCS # 12 ??), puede emitir el siguiente comando:
C:/Temp>openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key
-out exported-pem.key