2011-09-23 23 views
11

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.Convertir almacén de claves JKS firmado por CA a PEM

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 

Sólo 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 embarcadero con el mismo almacén de claves JKS imprime el 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 los rendimientos de OpenSSL que el 19 de error, ya no lo 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 con el servidor nginx y cliente Java? ¿Qué me estoy perdiendo?

+0

la respuesta a la última pregunta que se plantea es al final de mi respuesta a continuación. – djangofan

Respuesta

0

No estoy seguro de que es posible extraer la cadena con keytool pero se puede hacer con un pequeño programa en 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

9

Un problema bastante grande que encuentro con frecuencia es que, al generar el CSR para obtener nuestro certificado, el almacén de claves (almacén de claves jks con formato Sun) no genera la clave .key ni proporciona ninguna posibilidad de obtener la .key. Así que siempre terminé con un .pem/.rtrt sin posibilidad de utilizarlo 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 empezar, obtener una “copia” de su almacén de claves existente y saltar a la orden de 5º a continuación, o crear su propio así:

C:\Temp>keytool -genkey -alias tomcat -keyalg RSA -keystore 
keystore.jks -keysize 2048 -validity 730 -storepass changeit 

Entonces, opcionalmente, crear un CSR 2 años y luego importar la respuesta de la RSE, 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 conseguir este trabajo, y si usted ya tiene su archivo de almacén de claves JKS que se utiliza para un servidor de aplicaciones Tomcat, siga los siguientes pasos:

Primero, obtenga el certificado con formato DER (binario) en un archivo llamado "exported-der.CRT”:

C:\Temp>keytool -export -alias tomcat -keystore keystore.jks -file 
exported-der.crt 

Entonces, vista & verificarlo:

C:\Temp>openssl x509 -noout -text -in exported-der.crt -inform der 

Ahora se va a querer convertirlo a formato PEM, que está más ampliamente utilizado en aplicaciones como Apache y OpenSSL para hacer la conversión PKCS12:

C:\Temp>openssl x509 -in exported-der.crt -out exported-pem.crt 
-outform pem -inform der 

a continuación, descargar y utilizar ExportPriv para obtener la clave privada sin cifrar desde su almacén de claves:

C:\Temp>java ExportPriv <keystore> <alias> <password> > exported-pkcs8.key 

Por ahora probablemente se dé cuenta de que la clave privada se está exportando como formato PKCS # 8 PEM. Para conseguirlo en el formato RSA que funciona con Apache (PKCS # 12 ??) puede emitir el comando siguiente:

C:\Temp>openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key 
-out exported-pem.key 
6

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 certs con:

openssl pkcs12 -in keystore.p12 
Cuestiones relacionadas