Converting a Java Keystore into PEM Format
JavaEncryptionHttpsOpensslSsl CertificateJava Problem Overview
I am trying to convert from a Java keystore file into a PEM file using keytool and openssl applicactions. But I could not find a good way to do the conversion. Any ideas?
Instead of converting the keystore directly into PEM I tried to create a PKCS12 file first and then convert into relevant PEM file and Keystore. But I could not establish a connection using them. (Note that I just need a PEM file and a Keystore file to implement a secured connection. There is no restriction like "Start from a java keystore file". :) So starting from other formats is acceptable with my case)
But a direct conversion method from jks to pem is preferable.
Java Solutions
Solution 1 - Java
It's pretty straightforward, using jdk6 at least...
bash$ keytool -keystore foo.jks -genkeypair -alias foo
-dname 'CN=foo.example.com,L=Melbourne,ST=Victoria,C=AU' Enter keystore password:
Re-enter new password: Enter key password for(RETURN if same as keystore password):
bash$ keytool -keystore foo.jks -exportcert -alias foo |
openssl x509 -inform der -text Enter keystore password: asdasd Certificate: Data: Version: 3 (0x2) Serial Number: 1237334757 (0x49c03ae5) Signature Algorithm: dsaWithSHA1 Issuer: C=AU, ST=Victoria, L=Melbourne, CN=foo.example.com Validity Not Before: Mar 18 00:05:57 2009 GMT Not After : Jun 16 00:05:57 2009 GMT Subject: C=AU, ST=Victoria, L=Melbourne, CN=foo.example.com Subject Public Key Info: Public Key Algorithm: dsaEncryption DSA Public Key: pub: 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: <...snip...>bash$ keytool -importkeystore -srckeystore foo.jks
-destkeystore foo.p12
-srcstoretype jks
-deststoretype pkcs12 Enter destination keystore password:
Re-enter new password: Enter source keystore password:
Entry for alias foo successfully imported. Import command completed: 1 entries successfully imported, 0 entries failed or cancelledbash$ openssl pkcs12 -in foo.p12 -out foo.pem Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase:
bash$ openssl x509 -text -in foo.pem Certificate: Data: Version: 3 (0x2) Serial Number: 1237334757 (0x49c03ae5) Signature Algorithm: dsaWithSHA1 Issuer: C=AU, ST=Victoria, L=Melbourne, CN=foo.example.com Validity Not Before: Mar 18 00:05:57 2009 GMT Not After : Jun 16 00:05:57 2009 GMT Subject: C=AU, ST=Victoria, L=Melbourne, CN=foo.example.com Subject Public Key Info: Public Key Algorithm: dsaEncryption DSA Public Key: pub: 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: <...snip...>
bash$ openssl dsa -text -in foo.pem read DSA key Enter PEM pass phrase: Private-Key: (1024 bit) priv: 00:8f:b1:af:55:63:92:7c:d2:0f:e6:f3:a2:f5:ff: 1a:7a:fe:8c:39:dd pub: 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:
You end up with:
- foo.jks - keystore in java format.
- foo.p12 - keystore in PKCS#12 format.
- foo.pem - all keys and certs from keystore, in PEM format.
(This last file can be split up into keys and certificates if you like.)
Command summary - to create JKS keystore:
keytool -keystore foo.jks -genkeypair -alias foo \
-dname 'CN=foo.example.com,L=Melbourne,ST=Victoria,C=AU'
Command summary - to convert JKS keystore into PKCS#12 keystore, then into PEM file:
keytool -importkeystore -srckeystore foo.jks \
-destkeystore foo.p12 \
-srcstoretype jks \
-deststoretype pkcs12
openssl pkcs12 -in foo.p12 -out foo.pem
if you have more than one certificate in your JKS keystore, and you want to only export the certificate and key associated with one of the aliases, you can use the following variation:
keytool -importkeystore -srckeystore foo.jks \
-destkeystore foo.p12 \
-srcalias foo \
-srcstoretype jks \
-deststoretype pkcs12
openssl pkcs12 -in foo.p12 -out foo.pem
Command summary - to compare JKS keystore to PEM file:
keytool -keystore foo.jks -exportcert -alias foo | \
openssl x509 -inform der -text
openssl x509 -text -in foo.pem
openssl dsa -text -in foo.pem
Solution 2 - Java
I kept getting errors from openssl
when using StoBor's command:
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:
For some reason, only this style of command would work for my JKS file
keytool -importkeystore -srckeystore foo.jks \
-destkeystore foo.p12 \
-srcstoretype jks \
-srcalias mykey \
-deststoretype pkcs12 \
-destkeypass DUMMY123
The key was setting destkeypass
, the value of the argument did not matter.
Solution 3 - Java
Direct conversion from jks to pem file using the keytool
keytool -exportcert -alias selfsigned -keypass password -keystore test-user.jks -rfc -file test-user.pem
Solution 4 - Java
The keytool
command will not allow you to export the private key from a key store. You have to write some Java code to do this. Open the key store, get the key you need, and save it to a file in PKCS #8 format. Save the associated certificate too.
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();
Use OpenSSL utilities to convert these files (which are in binary format) to PEM format.
openssl pkcs8 -inform der -nocrypt < tmpkey.der > tmpkey.pem
openssl x509 -inform der < tmpcert.der > tmpcert.pem
Solution 5 - Java
Simplified instructions to converts a JKS file to PEM and KEY format (.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>
Solution 6 - Java
Converting a JKS KeyStore to a single PEM file can easily be accomplished using the following command:
keytool -list -rfc -keystore "myKeystore.jks" | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d" >> "myKeystore.pem"
Explanation:
-
keytool -list -rfc -keystore "myKeystore.jks"
lists everything in the 'myKeyStore.jks' KeyStore in PEM format. However, it also prints extra information. -
| sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d"
filters out everything we don't need. We are left with only the PEMs of everything in the KeyStore. -
>> "myKeystore.pem"
write the PEMs to the file 'myKeyStore.pem'.
Solution 7 - Java
In case you don't have openssl installed and you are looking for a quick solution, there is software called portcle which is very useful and small to download.
The disadvantage is that there is no command line as far as I know. But from the GUI, it is pretty straight forward to export a PEM private key:
- Open you JKS key store
- Right click over your private key entry and select export
- Select Private Key and certificates and PEM format
Solution 8 - Java
First dump the keystore from JKS to PKCS12
keytool -importkeystore -srckeystore ~/.android/debug.keystore -destkeystore intermediate.p12 -srcstoretype JKS -deststoretype PKCS12
Dump the new pkcs12 file into pem
- openssl pkcs12 -in intermediate.p12 -nodes -out intermediate.rsa.pem
You should have both the cert and private key in pem format. Split them up. Put the part between “BEGIN CERTIFICATE” and “END CERTIFICATE” into cert.x509.pem Put the part between “BEGIN RSA PRIVATE KEY” and “END RSA PRIVATE KEY” into private.rsa.pem Convert the private key into pk8 format as expected by signapk
openssl pkcs8 -topk8 -outform DER -in private.rsa.pem -inform PEM -out private.pk8 -nocrypt
Solution 9 - Java
I found a very interesting solution:
http://www.swview.org/node/191
Then, I divided the pair public/private key into two files private.key publi.pem and it works!
Solution 10 - Java
Well, OpenSSL should do it handily from a #12 file:
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
Maybe more details on what the error/failure is?
Solution 11 - Java
Try Keystore Explorer http://keystore-explorer.org/
KeyStore Explorer is an open source GUI replacement for the Java command-line utilities keytool and jarsigner. It does openssl/pkcs12 as well.
Solution 12 - Java
first create keystore file as
C:\Program Files\Android\Android Studio\jre\bin>keytool -keystore androidkey.jks -genkeypair -alias androidkey
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: FirstName LastName
What is the name of your organizational unit?
[Unknown]: Mobile Development
What is the name of your organization?
[Unknown]: your company name
What is the name of your City or Locality?
[Unknown]: CityName
What is the name of your State or Province?
[Unknown]: StateName
What is the two-letter country code for this unit?
[Unknown]: IN //press enter
> Now it will ask to confirm
Is CN=FirstName LastName, OU=Mobile Development, O=your company name, L=CityName, ST=StateName, C=IN correct? [no]: yes
Enter key password for
> key has been generated, now you can simply get pem file using following command
C:\Program Files\Android\Android Studio\jre\bin>keytool -export -rfc -alias androidkey -file android_certificate.pem -keystore androidkey.jks
Enter keystore password:
Certificate stored in file
Solution 13 - Java
open your terminal and going to jks file location and write this >>>> keytool -export -rfc -alias key0 -file android_certificate.pem -keystore androidkey.jks
Solution 14 - Java
I just leave following two commands here that does the job
# openssl pkcs12 -info -nodes -in /srv/apache-tomcat-8.5.72/conf/cert.jks -nokeys 2>&1| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > server.crt
Enter Import Password:
# openssl pkcs12 -info -nodes -in /srv/apache-tomcat-8.5.72/conf/cert.jks -nocerts 2>&1| sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' > server.key
Enter Import Password:
Solution 15 - Java
Suppose your keystore file is abcd.jks and its present at C:\Data,
try this in cmd window, at the location where the file is present:
keytool -export -rfc -keystore C:\Data\abcd.jks -alias abcd -file C:\Data\abcd.pem
Give password next, when prompted, and you will get the converted format at the location specified
Solution 16 - Java
> Converting a Java Keystore into PEM Format
The most precise answer of all must be that this is NOT possible.
A Java keystore is merely a storage facility for cryptographic keys and certificates while PEM is a file format for X.509 certificates only.