2011-09-23 118 views
11

我有一個JKS密鑰庫,證書由CA簽名。我需要將它導出爲PEM格式才能與nginx一起使用。我需要這樣做,它包括整個鏈,以便我的客戶可以驗證簽名。將CA簽名的JKS密鑰庫轉換爲PEM

如果我做這樣的事情:

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

它只包括最低級證書。驗證失敗:

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

從Java:

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

而碼頭與同JKS密鑰庫打印如下:

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

儘管OpenSSL的回報率是19的錯誤,它不再是Java HttpsURLConnection的一個問題,這就是我所關心的。

所以,我怎麼能出口整個產業鏈從JKS的格式(例如,PEM),它與兩個nginx的服務器和Java客戶端的工作?我錯過了什麼?

+0

回答最後一個問題,你問是我的回答如下結束。 – djangofan

回答

0

我不知道這是可能的keytool提取鏈,但它可以與一個小型的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(); 
    } 
} 

此代碼應該寫鏈的所有證書在DER格式提交的目錄。

9

我經常遇到的一個相當大的問題是,在生成CSR以獲取我們的證書時,密鑰庫(Sun格式化的jks密鑰庫)不會輸出.key或提供任何獲取.key的工具。所以我總是以.pem/.crt結尾,沒有辦法將它與Apache2一起使用,Apache2無法讀取像Tomcat那樣的JKS密鑰庫,但需要一個未打包的.key + .pem/.crt對。

要開始,得到「複製」您現有的密鑰庫及以下跳到第五命令,或者創建自己這樣的:

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

然後,可選,創建一個2年的CSR,然後進口CSR響應,在接下來的3個步驟:

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 

得到這個工作,如果你已經有了,你使用的Tomcat應用服務器的JKS密鑰庫文件,請按照下列步驟操作:

首先,獲取DER(二進制)格式的證書到一個名爲「exported-der」的文件中。CRT」:

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

然後,查看&驗證:

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

現在,你會希望將其轉換爲PEM格式,使用更廣泛的應用,如Apache和OpenSSL的做在PKCS12轉換:

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

然後,下載並使用ExportPriv從密鑰庫獲得加密私鑰:

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

現在你可能已經意識到,私鑰被導出爲PKCS#8 PEM格式。爲了得到它進入RSA格式與Apache(PKCS#12?)的作品,你可以發出以下命令:

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

您可以輕鬆地轉換一個JKS文件轉換成PKCS12文件:

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

然後,您可以提取私鑰和證書的任何使用:

openssl pkcs12 -in keystore.p12