最近发现公司之前申请的SSL证书是tomcat使用的jks格式的私key,但是我现在要放到nginx上使用,所以需要把jks格式的证书转base64的私key格式证书。

网上找了一些资料:

JKS(Java KeyStore)是Java的一个证书仓库,包括授权整数和公钥整数等。JDK提供了一个工具keytool用于管理keystore。转换步骤:

  • 1.使用keytool导出成PKCS12格式:
# keytool -importkeystore -srckeystore server.jks -destkeystore server.p12 -srcstoretype jks -deststoretype pkcs12
输入目标密钥库口令:  
再次输入新口令:
输入源密钥库口令:  
已成功导入别名 ca_root 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消
    1. 生成pem证书(包含了key,server证书和ca证书):
# 生成key 加密的pem证书
$ openssl pkcs12 -in server.p12 -out server.pem
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
 
# 生成key 非加密的pem证书
$ openssl pkcs12 -nodes -in server.p12 -out server.pem
Enter Import Password:
MAC verified OK
  • 3.单独导出key:
# 生成加密的key
$ openssl pkcs12 -in tankywoo.p12  -nocerts -out server.key
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
 
# 生成非加密的key
$ openssl pkcs12 -in tankywoo.p12 -nocerts -nodes -out server.key
Enter Import Password:
MAC verified OK
    1. 单独导出server证书:
$ openssl pkcs12 -in server.p12  -nokeys -clcerts -out server.crt
Enter Import Password:
MAC verified OK
    1. 单独导出ca证书:
$ openssl pkcs12 -in server.p12  -nokeys -cacerts -out ca.crt
Enter Import Password:
MAC verified OK

好了,我现在只需要把私key转出来就行,其它的PEM证书已经有了:

    1. 先转成p12,这一步好像是成功的。
[root@test-204 ]# keytool -importkeystore -srckeystore server.jks -destkeystore server.p12 -srcstoretype jks -deststoretype pkcs12
Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
Enter key password for <lixinwebssl>
Entry for alias lixinwebssl successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled
    1. 从p12转到key,这一步出错了。
[root@test-204 ]# openssl pkcs12 -in server.p12 -nocerts -nodes -out server.key
Enter Import Password:
MAC verified OK
Error outputting keys and certificates
140367235598152:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:596:
140367235598152:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error:p12_decr.c:104:
140367235598152:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs

然后就卡在这了,不停的google,发现一个老外也碰到过类似的问题,他提出了几个思考:

When I was trying to export my private key from the KeyStore file, I encountered an file password issue, which is worth mentioning here.

See the OpenSSL error message displayed below:

C:\herong>\local\jdk\bin\keytool -importkeystore 
   -srckeystore herong.jks -srcstoretype jks -srcstorepass HerongJKS
   -srcalias herongyang.com
   -destkeystore test.p12 -deststoretype pkcs12 -deststorepass TestP12
   -destalias 1

C:\herong>\local\gnuwin32\bin\openssl pkcs12 -in Test.p12 
   -passin pass:TestP12 -nocerts -out test_key.pem 
   -des -passout pass:TestKey

MAC verified OK
Error outputting keys and certificates
3812:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:
   bad decrypt:./crypto/evp/evp_enc.c:461:
3812:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 
   cipherfinal error:./crypto/pkcs12/p12_decr.c:97:
3812:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:
   pkcs12 pbe crypt error:./crypto/pkcs12/p12_decr.c:123:

So what’s wrong with the PKCS12 file, Test.p12? Why OpenSSL can not decrypt my private key from Test.p12? Here is what I think:

* In the original KeyStore file, Herong.jks, there are 2 separate passwords used: a. Key password, "HerongJKS", used to encrypt my private key; b. File password, "HerongJKS", used to encrypt the entire KeyStore file.

* In my "keytool -importkeystore" command, I did not specify the source key password. But "keytool" is smart enough to use the source file password to decrypt the private key.

* Also in my "keytool -importkeystore" command, I did not specify the destination key password. But "keytool" is stupid enough to reuse the source key password as the destination key password. "keytool" generate the destination PKCS12 file, Test.p12, with 2 different passwords: a. Key password, "HerongJKS", used to encrypt my private key; b. File password, "TestP12", used to encrypt the entire PKCS12 file.

* When executed the OpenSSL "pkcs12" command, I only specified the PKCS12 file password, "TestP12". There is no option for me to specify the key password, which is different than the file password. This is causing "pkcs12" command to fail.

Obviously, to avoid this problem, you have to set the key password and the file password with the same value with “keytool”. See tutorials in previous sections on how to do this.

原文链接: http://www.herongyang.com/PKI/Intermediate-CA-OpenSSL-pkcs12-Decrypt-Error.html

根据他说的几个可能的问题,发现应该是keytool这个工具对相关参数的处理可能有些问题,所以改成下面的参数就行了:

    1. 先转成p12
[root@test-204 ]# keytool -importkeystore -srckeystore server.jks -srcstoretype jks -srcstorepass password -srcalias lixinwebssl -destkeystore server.p12 -deststoretype pkcs12 -srckeypass password  -deststorepass 123456 --destkeypass 123456 -destalias lixinwebssl -v

 

    1. 从p12转到key,这回没报错了。
[root@test-204 ]# openssl pkcs12 -in server.p12 -nocerts -nodes -out server.key
Enter Import Password:
MAC verified OK