将Java密钥库转换为PEM格式


132

我正在尝试使用keytool和openssl应用程序将Java密钥库文件转换为PEM文件。但是我找不到进行转换的好方法。有任何想法吗?

我没有先将密钥库直接转换为PEM,而是尝试先创建PKCS12文件,然后再转换为相关的PEM文件和密钥库。但是我无法使用它们建立连接。(请注意,我只需要一个PEM文件和一个密钥库文件即可实现安全连接。没有类似“从Java密钥库文件开始”这样的限制。

但是从jks到pem的直接转换方法是可取的。

Answers:


214

这非常简单,至少使用jdk6 ...

bash $ keytool -keystore foo.jks -genkeypair -alias foo \
        -dname'CN = foo.example.com,L =墨尔本,ST =维多利亚,C = AU'
输入密钥库密码:  
重新输入新的密码: 
输入密钥密码 
        (如果与密钥库密码相同,则返回):  
bash $ keytool -keystore foo.jks -exportcert -alias foo | \
       openssl x509-通知der-文本
输入密钥库密码:asdasd
证书:
    数据:
        版本:3(0x2)
        序列号:1237334757(0x49c03ae5)
        签名算法:dsaWithSHA1
        发行者:C = AU,ST = Victoria,L = Melbourne,CN = foo.example.com
        有效期
            不早于:2009年3月18日格林尼治标准时间
            2009年6月16日00:05:57 GMT
        主题:C = AU,ST = Victoria,L =墨尔本,CN = foo.example.com
        主题公开密钥信息:
            公钥算法:dsaEncryption
            DSA公钥:
                酒馆: 
                    00:e2:66:5c:e0:2e:da:e0:6b:a6:aa:97:64:59:14:
                    7e:a6:2e:5a:45:f9:2f:b5:2d:f4:34:27:e6:53:c7:
 

bash $ keytool -importkeystore -srckeystore foo.jks \
       -destkeystore foo.p12 \
       -srcstoretype jks \
       -deststoretype pkcs12
输入目标密钥库密码:  
重新输入新的密码: 
输入源密钥库密码:  
别名foo的条目已成功导入。
导入命令已完成:成功导入了1个条目,失败或取消了0个条目

bash $ openssl pkcs12 -in foo.p12 -out foo.pem
输入导入密码:
MAC认证
输入PEM密码:
验证-输入PEM密码:

bash $ openssl x509 -text -in foo.pem
证书:
    数据:
        版本:3(0x2)
        序列号:1237334757(0x49c03ae5)
        签名算法:dsaWithSHA1
        发行者:C = AU,ST = Victoria,L = Melbourne,CN = foo.example.com
        有效期
            不早于:2009年3月18日格林尼治标准时间
            2009年6月16日00:05:57 GMT
        主题:C = AU,ST = Victoria,L =墨尔本,CN = foo.example.com
        主题公开密钥信息:
            公钥算法:dsaEncryption
            DSA公钥:
                酒馆: 
                    00:e2:66:5c:e0:2e:da:e0:6b:a6:aa:97:64:59:14:
                    7e:a6:2e:5a:45:f9:2f:b5:2d:f4:34:27:e6:53:c7:
 

bash $ openssl dsa -text -in foo.pem
读取DSA密钥
输入PEM密码:
私钥:(1024位)
私人:
    00:8f:b1:af:55:63:92:7c:d2:0f:e6:f3:a2:f5:ff:
    1a:7a:fe:8c:39:dd
酒馆: 
    00:e2:66:5c:e0:2e:da:e0:6b:a6:aa:97:64:59:14:
    7e:a6:2e:5a:45:f9:2f:b5:2d:f4:34:27:e6:53:c7:



您最终得到:

  • foo.jks-Java格式的密钥库。
  • foo.p12-PKCS#12格式的密钥库。
  • foo.pem-PEM格式的密钥库中的所有密钥和证书。

(如果需要,可以将最后一个文件分为密钥和证书。)


命令摘要-创建JKS密钥库:

keytool -keystore foo.jks -genkeypair -alias foo \
    -dname 'CN=foo.example.com,L=Melbourne,ST=Victoria,C=AU'

命令摘要-将JKS密钥库转换为PKCS#12密钥库,然后转换为PEM文件:

keytool -importkeystore -srckeystore foo.jks \
   -destkeystore foo.p12 \
   -srcstoretype jks \
   -deststoretype pkcs12

openssl pkcs12 -in foo.p12 -out foo.pem

如果您的JKS密钥库中有多个证书,并且只想导出与别名之一相关联的证书和密钥,则可以使用以下变体:

keytool -importkeystore -srckeystore foo.jks \
   -destkeystore foo.p12 \
   -srcalias foo \
   -srcstoretype jks \
   -deststoretype pkcs12

openssl pkcs12 -in foo.p12 -out foo.pem

命令摘要-比较JKS密钥库和PEM文件:

keytool -keystore foo.jks -exportcert -alias foo | \
   openssl x509 -inform der -text

openssl x509 -text -in foo.pem

openssl dsa -text -in foo.pem

12
此方法不支持可信证书:我认为这是PKS12格式的限制:java.sun.com/javase/6/docs/technotes/guides/security/jsse/…(关于java.security.KeyStoreException的部分:不支持TrustedCertEntry)
andygavin

2
我有一个较旧的JKS文件。我无法使用上述方法导出。通过将keytool arg'-destkeypass'设置为虚拟值,我终于能够做到这一点。'keytool'甚至提示警告说它正在忽略destkeypass值?没有其他技术会起作用。使用提示不起作用,只能从命令行参数起作用。必须是PKCS12导出中的错误,任何人都可以发表评论吗?
cmcginty 2012年

4
“ openssl pkcs12 -in foo.p12 -out foo.pem”引发以下错误输入导入密码:MAC验证正常输出密钥和证书时出错139848775526048:error:06065064:数字信封例程:EVP_DecryptFinal_ex:不良解密:evp_enc.c:539 :139848775526048:错误:23077074:PKCS12例程:PKCS12_pbe_crypt:pkcs12密码最终错误:p12_decr.c:104:139848775526048:错误:2306A075:PKCS12例程:PKCS12_item_decrypt_d2i:pkcs12 pbe加密错误:p12_dec。有什么解决方案?
Udara SS Liyanage

1
对其他人的警告,由于某种原因,keytool命令需要一段时间才能完成,我不得不等待30秒才能完成导出
Nicolas Mommaerts 2013年

1
@ UdaraS.SLiyanage:看看Casey对解决方案的回答
Nicolas Mommaerts 2013年

29

openssl使用StoBor的命令时,我不断收到错误消息:

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

由于某种原因,只有这种样式的命令才能用于我的JKS文件

keytool -importkeystore -srckeystore foo.jks \
   -destkeystore foo.p12 \
   -srcstoretype jks \
   -srcalias mykey \
   -deststoretype pkcs12 \
   -destkeypass DUMMY123

关键是设置destkeypass,参数的值无关紧要。


6
原因可以在这里找到:herongyang.com/PKI/…密码通关确实很重要
Nicolas Mommaerts 2013年

我对此评论表示赞同,但值得发表。在这里很难找到。
Richie Rich

15

keytool命令不允许您从密钥库中导出私钥。您必须编写一些Java代码才能执行此操作。打开密钥库,获取所需的密钥,并将其保存为PKCS#8格式的文件。也保存关联的证书。

KeyStore ks = KeyStore.getInstance("jks");
/* Load the key store. */
...
char[] password = ...;
/* Save the private key. */
FileOutputStream kos = new FileOutputStream("tmpkey.der");
Key pvt = ks.getKey("your_alias", password);
kos.write(pvt.getEncoded());
kos.flush();
kos.close();
/* Save the certificate. */
FileOutputStream cos = new FileOutputStream("tmpcert.der");
Certificate pub = ks.getCertificate("your_alias");
cos.write(pub.getEncoded());
cos.flush();
cos.close();

使用OpenSSL实用程序将这些文件(二进制格式)转换为PEM格式。

openssl pkcs8 -inform der -nocrypt < tmpkey.der > tmpkey.pem
openssl x509 -inform der < tmpcert.der > tmpcert.pem

谢谢erickson。结论是“我们不能仅通过使用keytool和openssl实用程序就可以将JKS直接转换为PEM”。我对么?
Chathuranga Chandrasekara

4
您只需要编写Java 1.4以下的代码-从Java 5开始,可以将keytool和openssl组合在一起,以从JKS-> PKCS#12-> PEM执行两阶段转换。但是,编写自己的密钥工具是从JKS-> PEM 执行直接转换的唯一方法。
Stobor

我认为这是从JDK 6开始的。但是可以,现在支持PKCS#12导入。
艾里克森(Erickson),2010年

13

使用keytool从jks直接转换为pem文件

keytool -exportcert -alias selfsigned -keypass password -keystore test-user.jks -rfc -file test-user.pem

10
是的,导出证书。但是,它不会导出关键信息...
Stobor

这是确切的简单的回答了我的数十个搜索keytooljboss文档页面没有成功。谢谢!
kratenko

15
这不导出私人关键信息
James

1
此出口公钥证书
麻美

我尝试运行此命令。它需要密码,请输入密钥库密码:keytool错误:java.io.IOException:密钥库被篡改,或者密码不正确。我已经使用过密码as(password),但是它抛出了同样的错误
Mohit Singh

9

将JKS文件转换为PEM和KEY格式(.crt和.key)的简化说明:

keytool -importkeystore -srckeystore <Source-Java-Key-Store-File> -destkeystore <Destination-Pkcs12-File> -srcstoretype jks -deststoretype pkcs12 -destkeypass <Destination-Key-Password>

openssl pkcs12 -in <Destination-Pkcs12-File> -out <Destination-Pem-File>

openssl x509 -outform der -in <Destination-Pem-File> -out <Destination-Crt-File>

openssl rsa -in <Destination-Pem-File> -out <Destination-Key-File>


2

使用以下命令可以轻松地将JKS KeyStore转换为单个PEM文件:

keytool -list -rfc -keystore "myKeystore.jks" | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d" >> "myKeystore.pem"

说明:

  1. keytool -list -rfc -keystore "myKeystore.jks"以PEM格式列出“ myKeyStore.jks”密钥库中的所有内容。但是,它还会打印其他信息。
  2. | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d"过滤掉我们不需要的所有内容。我们只剩下KeyStore中所有内容的PEM。
  3. >> "myKeystore.pem" 将PEM写入文件“ myKeyStore.pem”。

3
bash:!d“:找不到事件
user3217883 '16

1
@ user3217883您可以尝试使用类似的方法sed "s/^\-*BEGIN [A-Z]*\-*$//g;s/^\-*END [A-Z]*\-*$//g"(使用gnu sed),但是我不确定密钥库中是否有多个证书就足够了
Idriss Neumann

如果您得到bash: !d": event not found:对于bash来说,感叹号是使用命令的快捷键。要使用此答案,您需要使用单引号代替用作sed的-e选项的引号keytool -list -rfc -keystore "myKeystore.jks" | sed -e '/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d' >> "myKeystore.pem"
B.Adler,

不幸的是,这仅导出证书,而不导出私钥
Maddin

2

首先将密钥库从JKS转储到PKCS12

1. keytool -importkeystore -srckeystore〜/ .android / debug.keystore -destkeystore中间体.p12 -srcstoretype JKS -deststoretype PKCS12

将新的pkcs12文件转储到pem中

  1. openssl pkcs12 -in中间.p12-节点-out中间.rsa.pem

您应该同时拥有pem格式的证书和私钥。拆分它们。将“ BEGIN CERTIFICATE”和“ END CERTIFICATE”之间的部分放入cert.x509.pem。将“ BEGIN RSA PRIVATE KEY”和“ END RSA PRIVATE KEY”之间的部分放入private.rsa.pem。期望signapk

3. openssl pkcs8 -topk8-将DER-输入private.rsa.pem-通知PEM-将private.pk8 -nocrypt


1

好吧,OpenSSL应该方便地从#12文件执行此操作:

openssl pkcs12 -in pkcs-12-certificate-file -out pem-certificate-file
openssl pkcs12 -in pkcs-12-certificate-and-key-file -out pem-certificate-and-key-file

也许更多关于错误/故障是什么的细节?


1

如果您没有安装openssl,并且正在寻找一种快速的解决方案,则可以使用名为portcle的软件,该软件非常有用且下载量很小。

缺点是据我所知没有命令行。但是从GUI导出PEM私钥很简单:

  1. 打开您的JKS密钥库
  2. 右键单击您的私钥条目,然后选择导出
  3. 选择私钥和证书以及PEM格式

    使用Portcle从JKS导出PEM私钥



0

首先创建密钥库文件为

C:\ Program Files \ Android \ Android Studio \ jre \ bin> keytool -keystore androidkey.jks -genkeypair -alias androidkey

输入密钥库密码:
重新输入新密码:
您的名字和姓氏是什么?未知: 名字姓氏
组织单位的名称是什么?未知: 移动开发
您的组织名称是什么?未知: 您的公司名称
您所在的城市或地区的名称是什么?您所在州或省的名字是什么?
该单位的两个字母的国家/地区代码是什么?未知:IN //按Enter

现在它将要求确认

CN = FirstName姓氏,OU =移动开发,O =您的公司名称,L =城市名称,ST =州名,C = IN是否正确?[否]:

输入以下项的密钥密码(如果与密钥库密码相同,则返回):如果需要相同的密码,请按Enter

密钥已经生成,现在您可以使用以下命令简单地获取pem文件

C:\ Program Files \ Android \ Android Studio \ jre \ bin> keytool -export -rfc -alias androidkey -file android_certificate.pem -keystore androidkey.jks
输入密钥库密码:
证书存储在文件中


0

将Java密钥库转换为PEM格式

最准确的答案必须是这是不可能的。

Java密钥库仅是加密密钥证书的存储工具,而PEM仅是X.509证书的文件格式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.