将CA签名的JKS密钥库转换为PEM [英] Convert CA-signed JKS keystore to PEM
问题描述
我有一个CA签署的带有证书的JKS密钥库.我需要将其导出为PEM格式,以便与Nginx一起使用.我需要以包括整个链的方式来执行此操作,以便我的客户可以验证签名.
I have a JKS keystore with certicate signed by CA. I need to export it in PEM format in order to use it with nginx. I need to do it in such a way that it includes the whole chain, so that my client can verify the signature.
如果我做类似的事情:
keytool -exportcert -keystore mykestore.jks -file mycert.crt -alias myalias
openssl x509 -out mycert.crt.pem -outform pem -in mycert.crt -inform der
它仅包括最低级别的证书.验证失败:
It only includes the lowest level certificate. The verification fails:
$ 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密钥库的Jetty会打印以下内容:
Whereas Jetty with the same JKS keystore prints the following:
$ 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
不再是问题,这就是我所关心的全部问题.
Although openssl returns that 19 error, it no longer is an issue for Java HttpsURLConnection
and that is all I care about.
那么,如何从JKS导出 整个链 ,这种格式适用于Nginx服务器和Java客户端,所以可以使用?我想念什么?
So, how can I export the whole chain from JKS in a format (e.g. PEM) which works with both nginx server and Java client? What am I missing?
推荐答案
我经常遇到的一个相当大的问题是,在生成CSR以获取我们的证书时,密钥库(Sun格式化的jks密钥库)不会输出.密钥或提供任何获取.key的便利.因此,我总是以.pem/.crt结尾,无法与Apache2一起使用.Apache2无法像Tomcat一样读取JKS密钥库,而是需要一个未打包的.key + .pem/.crt对.
A rather large problem that I frequently encounter is that, when generating the CSR to get our certificate, the keystore (Sun formatted jks keystore) does not output the .key or provide any facility for obtaining the .key. So I always had ended up with a .pem/.crt with no way of using it with Apache2, which cannot read a JKS keystore like Tomcat can, but instead requires a unpackaged .key + .pem/.crt pair.
首先,获取现有密钥库的副本"并跳到下面的第5条命令,或者像这样创建自己的密钥库:
To start, get a "copy" of your existing keystore and skip to the 5th command below, or create your own like this:
C:\Temp>keytool -genkey -alias tomcat -keyalg RSA -keystore
keystore.jks -keysize 2048 -validity 730 -storepass changeit
然后(可选)创建一个为期两年的CSR,然后在接下来的3个步骤中导入CSR响应:
Then, optionally, create a 2-year CSR and then import the CSR response, in the next 3 step process:
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密钥库文件,请执行以下步骤:
To get this working, and if you already have your JKS keystore file that you use for a Tomcat application server, follow the following steps:
首先,将DER(二进制)格式的证书放入名为"exported-der.crt"的文件中:
First, get the DER (binary) formatted certificate into a file called "exported-der.crt":
C:\Temp>keytool -export -alias tomcat -keystore keystore.jks -file
exported-der.crt
然后,查看&验证一下:
Then, view & verify it:
C:\Temp>openssl x509 -noout -text -in exported-der.crt -inform der
现在,您需要将其转换为PEM格式,该格式在Apache等应用程序中使用更广泛,并由OpenSSL进行PKCS12转换:
Now you will want to convert it to PEM format, which is more widely used in applications such as Apache and by OpenSSL to do the PKCS12 conversion:
C:\Temp>openssl x509 -in exported-der.crt -out exported-pem.crt
-outform pem -inform der
然后,下载并使用ExportPriv从您的密钥库中获取未加密的私钥:
Then, download and use ExportPriv to get the unencrypted private key from your keystore:
C:\Temp>java ExportPriv <keystore> <alias> <password> > exported-pkcs8.key
现在您可能已经意识到,私钥已被导出为PKCS#8 PEM格式.要将其转换为可与Apache(PKCS#12 ??)一起使用的RSA格式,可以发出以下命令:
By now you probably realize, the private key is being exported as PKCS#8 PEM format. To get it into the RSA format that works with Apache (PKCS#12??) you can issue the following command:
C:\Temp>openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key
-out exported-pem.key
这篇关于将CA签名的JKS密钥库转换为PEM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!