2011-09-23 17 views
11

Possiedo un archivio di chiavi JKS con certificato firmato da CA. Ho bisogno di esportarlo in formato PEM per poterlo usare con nginx. Ho bisogno di farlo in modo che includa l'intera catena, in modo che il mio cliente possa verificare la firma.Convertire il keystore JKS firmato da CA a PEM

Se faccio qualcosa di simile:

keytool -exportcert -keystore mykestore.jks -file mycert.crt -alias myalias 
openssl x509 -out mycert.crt.pem -outform pem -in mycert.crt -inform der 

Esso comprende solo il certificato di livello più basso. La verifica ha esito negativo:

$ 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) 

Da Java:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 

Mentre Pontile con la stessa chiavi JKS stampa il seguente:

$ 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) 

Anche se i rendimenti di OpenSSL che il 19 errore, non lo è più un problema per Java HttpsURLConnection e questo è tutto ciò che mi interessa.

Quindi, come posso esportare l'intera catena da JKS in un formato (ad esempio PEM), che funziona sia con server di nginx e client Java? Cosa mi manca?

+0

la risposta all'ultima domanda che hai posto è alla fine della mia risposta qui sotto. – djangofan

risposta

0

io non sono sicuro che è possibile estrarre la catena con keytool ma può essere fatto con un piccolo programma 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(); 
    } 
} 

Questo codice dovrebbe scrivere tutti i certificati della catena in formato DER nel directory presentata.

9

Un problema piuttosto grande che incontro spesso è che, quando si genera il CSR per ottenere il nostro certificato, il keystore (keystore jks formattato Sun) non emette il tasto .key o fornisce alcuna funzione per ottenere il .key. Così ho sempre finito con un .pem/.crt senza alcun modo di usarlo con Apache2, che non può leggere un archivio di chiavi JKS come Tomcat, ma richiede invece una coppia .key + .pem/.crt non pacchettizzata.

Per iniziare, avere una “copia” del vostro keystore esistente e passare al 5 ° comando di sotto, o creare il proprio in questo modo:

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

Poi, eventualmente, creare un 2 anni CSR e poi importare la risposta CSR, nel successivo processo in 3 step:

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 

per ottenere questo lavoro, e se avete già il vostro file di archivio chiavi JKS che si usa per un application server Tomcat, seguire i seguenti passi:

Innanzitutto, ottenere il certificato formattato DER (binario) in un file denominato "exported-der.crt”:

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

Poi, vista & verificarlo:

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

Ora si vuole convertirlo in formato PEM, che è più ampiamente utilizzato in applicazioni come Apache e OpenSSL da fare la conversione PKCS12:

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

Poi, scaricare e utilizzare ExportPriv per ottenere la chiave privata in chiaro dal vostro chiavi:

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

Ormai probabilmente ci si rende conto che la chiave privata viene esportata come formato PEM PKCS # 8. Per farlo nel formato RSA che funziona con Apache (PKCS # 12 ??), è possibile eseguire il seguente comando:

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

si può facilmente convertire un file JKS in un file PKCS12:

keytool -importkeystore -srckeystore keystore.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore keystore.p12 

è quindi possibile estrarre la chiave privata e qualsiasi certs con:

openssl pkcs12 -in keystore.p12 
Problemi correlati