Converting a Java Keystore into PEM Format
Solution 1
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: 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 cancelled bash$ 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: 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
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
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
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
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>
Related videos on Youtube
Chathuranga Chandrasekara
A seasoned professional with 10+ years of Industry experience. The core competencies are, 1. Full Stack Solutions Architecture 2. Design and Implementation of Internet of Things (IoT) Software and Hardware/Firmware Programming Languages - Java | Python | NodeJS | JavaScript | TypeScript Front End Frameworks - Angular | React | Backbone | Bootstrap | Material Dependency Injection - Spring ORM - Hibernate Microservices - Spring Boot Batch Processing - Spring Batch Containerization - Docker Orchestration – Kubernetes Databases – MySQL | Postgres SQL | MS SQL Server NoSQL - MongoDB | Cassendra Build Tools – Maven | Gradle CI/CD – Jenkins | Ansible | Chef Testing - JUnit | Jasmine | Karma | RestAssured | Selenium Caching - Redis | Guava Dashboarding - Kibana | Banana Reporting - Jasper | Penthaho Health Monitoring – Prometheous | OpenTSDB | Ngios Messaging – RabbitMQ | Kafka API Gateways – Zuul | WSO2 API Manager | Nginx | Kong Cloud Services – AWS | OpenShift Identity Providers - KeyCloak | Apereo CAS REST Documentation - Swagger REST Security - JWT | OAuth2 Protocols - CoAP | STOMP | XMPP | TLS | REST | SOAP | MQTT | AMQP Source Management - Git | Subversion | Mercural Deep Learning & Numerical Calculation - Keras | Tensorflow | Caffe | Pandas | Numpy Image Processing and Computer Vision - OpenCV Project Management - Jira | ScrumWorks Programmable Hardware - Arduino | Rasberry Pi | PIC | ESP 32| ESP8266 GPRS & NB-IoT - SIM 800 | SIM 900 | SIM 7000 IoT Prototyping - NodeRed Search Engines - Elastic | Solr | Fast ESP Mobile – Android | Telerik NativeScript | Ionic 2 | React Native My other interests are, 1. Machine Learning 2. Deep Learning / Artificial Neural Networks 3. Artificial Intelligence
Updated on February 04, 2022Comments
-
Chathuranga Chandrasekara about 2 years
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.
-
Chathuranga Chandrasekara about 15 yearsThanks erickson.. The conclusion is "We can't perform a direct conversion from JKS to PEM by just using keytool and openssl utilities". Am I correct?
-
andygavin over 14 yearsTrusted certificates are not supported in this method: this is a restriction of the PKS12 format I believe see: java.sun.com/javase/6/docs/technotes/guides/security/jsse/… (section on java.security.KeyStoreException: TrustedCertEntry not supported)
-
Stobor over 14 years@andygavin: Indeed; this is true. While the PKCS format can hold arbitrarily many certificates, it does not have a field to indicate whether the certificate is trusted or not. However, the question was about how to end up with a PEM (PKCS#7) file, which also doesn't have this trust information, so it's not an issue of the process...
-
Stobor over 13 yearsYou only need to write code up to Java 1.4 - from Java 5 onwards, keytool and openssl can be combined to perform a two stage conversion from JKS -> PKCS#12 -> PEM. However, writing your own key tool is the only way to perform DIRECT CONVERSION from JKS -> PEM.
-
brady over 13 yearsI think it's from JDK 6 onward. But yes, a PKCS #12 import is now supported.
-
Stobor almost 13 yearsYep, that exports the certificate. However, it does not export the key information...
-
cmcginty over 11 yearsI have an older JKS file. I could not export using the method above. I finally was able to do it by setting keytool arg '-destkeypass' to a dummy value. 'keytool' even prompts a warning saying it is ignoring destkeypass value? No other technique would work. Using the prompts did not work, only works from the command line argument. Must be a bug in the PKCS12 export, can anyone comment?
-
Udara S.S Liyanage about 11 years"openssl pkcs12 -in foo.p12 -out foo.pem" throws the following error Enter Import Password: MAC verified OK Error outputting keys and certificates 139848775526048:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539: 139848775526048:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error:p12_decr.c:104: 139848775526048:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:p12_decr.c:130. What is the solution for this?
-
Nicolas Mommaerts almost 11 yearsa warning for other people, the keytool command takes a while to complete for some reason, I had to wait 30 seconds until the export was done
-
Nicolas Mommaerts almost 11 years@UdaraS.SLiyanage: look at Casey's answer for the solution
-
Nicolas Mommaerts almost 11 yearsThe reasoning can be found here: herongyang.com/PKI/… The destkeypass DOES matter btw
-
Richie Rich about 10 yearsI upvoted this comment but it deserves it's own post. It was tough to find here.
-
kratenko about 9 yearsThis is the exact simple answer to what I was searching on dozens of
keytool
andjboss
doc pages without success. Thanks! -
James almost 9 yearsTHIS DOES NOT EXPORT PRIVATE KEY INFORMATION
-
jnnnnn over 8 yearsI got errors (keytool error: java.io.IOException: DER input, Integer tag error) until I deleted the destination keystore file before running the command. Make sure that the destination keystore file does not exist before running the command.
-
asami over 8 yearsThis exports public key certificate
-
user3217883 almost 8 yearsbash: !d": event not found
-
Mohit Singh about 7 yearsI tried running this command. It requires password,Enter keystore password: keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect. I have used password as(password) but it was throwing same error
-
Idriss Neumann about 7 years@user3217883 You could try something like
sed "s/^\-*BEGIN [A-Z]*\-*$//g;s/^\-*END [A-Z]*\-*$//g"
instead (with gnu sed) but i'm not sure that's enough if there are more than one cert in your keystore -
B.Adler over 4 yearsif you're getting
bash: !d": event not found
: for bash an exclamation mark is a short key to use a command. To use this answer you need to use apostrophes in place of the quotes for the option used as -e for sedkeytool -list -rfc -keystore "myKeystore.jks" | sed -e '/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d' >> "myKeystore.pem"
-
Maddin over 4 yearsUnfortunately, this only exports the certificate, not the private key
-
Sultan Ali over 4 yearswhere it will save the
pem
file? -
dave_thompson_085 about 3 yearsThis doesn't add anything useful to the 2011 answer by sanghaviss and it outputs only the cert not the private key
-
dave_thompson_085 about 3 yearsIn OpenSSL versions 1.0.0 (released 2010) and up,
openssl pkcs12
should already output the privatekey in PKCS8 format -- but PEM, so if you need DER you do need either the specific conversion byopenssl pkcs8 -topk8 -outform der
or the generic one for a single isolated PEM block (only)openssl base64 -d
-
dave_thompson_085 about 3 yearsThis is quite wrong. PEM files are widely used for certificates, CRLs, (PKCS10) CSRs, and private keys, and less widely for PKCS7/CMS messages (including p7b/p7c cert and/or CRL bundles), bare public keys, parameters, and more rarely things like OpenSSL saved-session blocks and OCSP messages. For the officially standard ones see RFC7468.
-
wh81752 about 3 years@dave_thompson_085 - True, that PEM is not only about X.509 certificates. However my point has been that you can store anything within a Java Keystore as long as it complies with the (empty) interface of docs.oracle.com/javase/7/docs/api/java/security/… - while PEM appears to be bound to some Crypto standards (and not to an arbitrary base64 encoding).
-
dave_thompson_085 about 3 yearsAll JCA APIs including KeyStore are (intentionally) very broad, but actual implementations behind those APIs need not be. For important examples JKS and PKCS12 support only certificate types for which a certificatefactory exists, and the only certificatefactory that exists is X.509. PEM (RFC1421) 'printable encoding' can be applied to any binary data, although it is mostly used for ASN.1 data (mostly DER, some BER e.g. PKCS7/CMS) which is still a very wide set. (The very similar MIME base64 encoding, defined almost simultaneously, is used for all kinds of data.)
-
solstice333 almost 3 yearsIf you're using git-bash on windows, you may want to prefix
openssl ...
withwinpty openssl ...
-
kevinarpe almost 3 years@user3217883 Try single quotes instead of double quotes, e.g.,
... | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d" >> ...
-
Devendra Singraul almost 3 yearsThis exports public.pem certificate. How to find private.pem