Exploring Key Stores and Public Certificates — JKS (2024)

Seralahthan

·

Follow

12 min read

·

Feb 12, 2022

--

Exploring Key Stores and Public Certificates — JKS (2)

In this post let’s explore the fundamentals of a Java Key Store (JKS) and a Public Key Certificate.

!!! Caution: Long Post !!!

This post is going to be a bit elaborate and lengthy, so, if you are looking for a quick cheat sheet of commands… Here you go…

The key store is a storage facility to store cryptographic keys and certificates used for SSL communications.

There are different types of key stores available in Java depending on the type of entries the keystore can store and how the keystore can store the entries. Java Key Store (JKS) is one of the widely used key store types available in Java.

Each key store can hold a unique set of keys depending on the type.
In General, A key store contains the following types of keys,

  • Private Key Entry/Entries
    (With a certificate chain for the corresponding Public Key Entry/Entries).
  • Trusted Certificates
    (Third-party Public keys + Certificate Chains)
  • Secret Key Entry/Entries

Private Key (PrivateKeyEntry)

It is the key used for asymmetric encryption and signing a digital signature. The private key entry is password protected.

Generally, a JKS type of key store can have only one private key entry in a key store file. Some key store types, allow having multiple private key entries in a single key store.

Along with the private key entry, a certificate chain for the corresponding public key entry also will be there.

Trusted Certificates (TrustedCertificateEntry)

It holds the third-party public keys used for asymmetric encryption and digital signature validation along with the Trusted Certificate Chains.

A key store can hold any number of Trusted Certificates.

Secret Key (SecretKeyEntry)

It is the key used for symmetric encryption.
Generally, a JKS doesn’t have SecretKey entries.

There are different types of Java key stores depending on the entries a key store can store and how these entries are stored in the key store. Some of the popular Java key stores are JKS, JCEKS, PKCS12, DKS, and BKS.

Let’s explore some of these Java key store types and their differences.

Is a repository of security certificates — either authorisation certificates or public key certificates — plus corresponding private keys, used for instance in SSL encryption.

Implementation can be found at java.security.KeyStore
This key store is Java-specific and usually has an extension of .jks
(eg: wso2carbon.jks)

According to the Java specification, JKS key store manages different types of entries. Each type of entry implements the KeyStore.Entry interface.
Three basic KeyStore.Entry implementations are provided:

  • KeyStore.PrivateKeyEntry
  • KeyStore.SecretKeyEntry
  • KeyStore.TrustedCertificateEntry

Refer to the Java documentation for further details.

Features of JKS

  • Since this is a Java-specific key store cannot be used with other programming languages.
  • It doesn’t support storing Secret Key entries.
  • Only a single Private Key entry can be stored in a key store file, multiple Private Key entries are not allowed.
  • Private Key entries stored in the JKS key store can’t be extracted.

Now let’s see how we can implement a key store using Java.
Java provides few options to work with key stores :

  • Writing a Java code
  • Using the inbuilt tool named “keytool which comes along with the JDK.

Keytool is a command-line tool that is shipped along with the JDK.
It can be used to create keystore, generate keys, import and export certificates, etc.

Note that keytool is only available with Java JDK installations and not with Java JRE runtimes.

Create a JKS with Private & Public key pairs using Keytool

keytool -genkeypair -v -alias sample -keyalg RSA -keysize 2048 \
-validity 365 -keystore sample_keystore.jks

This is achieved by using the keytool ‘-genkeypair’ option, in earlier version of keytool ‘-genkey’ option was used which is still supported for backward compatibility.

The above command will create a JKS key store named sample_keystore.jks which contains, a 2048 bit Private/Public key pair aliased “sample” created using the RSA cryptographic algorithm and a self-signed certificate (SHA256withRSA) with a validity period of 365 days.

Above command,

  1. Generates a RSA 2048 bit Public and Private key pair,
  2. Wraps the public key into an X.509 v3 self-signed certificate signed by SHA256withRSA with a validity period of 365 days,
  3. Self-signed certificate is then stored as a single-element certificate chain.
  4. Certificate chain and the Private Key are stored in a new keystore ‘sample_keystore.jks’ entry identified by alias ‘sample’.

While executing the above command to generate the key store, you will be prompted for the “CN”, “key store password” and “key password” as below,

Exploring Key Stores and Public Certificates — JKS (3)

CN should generally match the hostname of the server.
Generally is good to use the same password for the keystore password and the key password (for the alias “sample”).

Some servers like Tomcat Catalina Server by default use the “key store password” as the “key password” for the connectors if not explicitly mentioned.

Not all the parameters are required to be passed in the above keytool command, following are the optional defaults for the keystore creation command,

-alias: mykey
-keyalg: DSA
-keysize: 2048 bit (for both RSA and DSA)
-validity: 90 days
-storetype: JKS (property value fetched from 'java.security.keystore.type' from Java jdk/jre)

Refer to the keytool documentation for further details.

Configuring Tomcat Catalina Server with the JKS

If you are using a Tomcat Catalina Server and using separate “key password” and “key store password”, you need to explicitly configure it in the server.xml file of the Tomcat Server found in the <TOMCAT_HOME>/conf/ directory.

<!-- Define an SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="${path_to_keystore}/sample_keystore.jks"
keystorePass="keystore_password"
keyPass="key_password"
clientAuth="false" sslProtocol="TLS"/>

Note that keystorePass is used to specify the “key store password” while keyPass is used to specify the “key password”.

Refer to the Tomcat documentation for further details.

List entries of JKS

Now let’s list the key store entries of the “sample_keystore.jks

keytool -list -v -keystore sample_keystore.jks

The entries will look like below with a PrivateKeyEntry and a Certificate chain

Exploring Key Stores and Public Certificates — JKS (4)

Converting a JKS to PKCS12 keystore

As you would have noticed when we created a JKS key store using the key tool, there was this following Warning message,

Warning:
The JKS keystore uses a proprietary format.
It is recommended to migrate to PKCS12 which is an industry standard format.

JKS and JCEKS key stores are in Java proprietary format, and it is recommended to use PKCS12 format key store as it is the standard industry format. Later in this post, we will discover more on JCEKS and PKCS12 key store formats.

Let’s convert the “sample_keystore.jks” to a PKCS12 key store with .pfx extension.

keytool -importkeystore -srckeystore sample_keystore.jks \
-destkeystore sample_keystore.pfx -deststoretype pkcs12

A successful conversion will result in the following outcome

Exploring Key Stores and Public Certificates — JKS (5)

Export public certificate from JKS in DER format (binary-encoded format)

Now, let’s try to export the Public key certificate from the “sample_keystore.jks” with alias “sample to “sample.crt” Public certificate file.

keytool -exportcert -alias sample -file sample.crt \
-keystore sample_keystore.jks

Results will look like below,

Exploring Key Stores and Public Certificates — JKS (6)

If you try to view the content of the “sample.crt” file it would be in a
non-human readable format. This is because the Public certificate generated is in a binary encoded certificate.

Public certificates can have content with the following two encodings:

  • Binary DER-encoded certificates (non-human readable)
  • ASCII (Base64) PEM-encoded certificates (human-readable)

DER: Distinguished Encoding Rules (Subset of Basic Encoding Rules of ASN.1)
PEM: Privacy-Enhanced Mail

Note:
Encoding is a process of transforming the data into a different format using a publicly available schema. It can easily be reversed. The purpose of encoding is not to keep the information secure rather it is to transform the data into a format safe to be consumed by different systems.

Public certificate can have the following common file extensions:

  • “.crt” extension: Certificate may be encoded as binary DER Or ASCII PEM.
  • “.der extension: Certificate encoded with binary DER.
  • “.pem” extension: Certificate encoded with ASCII (Base64).

So, to get the Public certificate in a human-readable format we can export it either using PEM encoded .crt extension Or PEM encoded .pem extension.

keytool -exportcert -alias sample -file sample.pem \
-keystore sample_keystore.jks

Exporting the Public certificate with .pem extension as above will still result in a binary encoded Public key certificate.

This is because, regardless of the -file format provided, keytool’s -exportcert command will by default always create the Public key certificate as a binary encoded certificate.

Export public certificate from JKS in PEM format
(ASCII Base64 human-readble format)

In order to export the Public certificate from the JKS key store in a PEM format, we need to pass an additional -rfc argument while using the
-exportcert command.

keytool -exportcert -alias sample -file sample.pem \
-keystore sample_keystore.jks -rfc

Content of the “sample.pem Public certificate will look like below,

Exploring Key Stores and Public Certificates — JKS (7)

As you can see from above PEM format Public certificate has the
— — -BEGIN CERTIFICATE — — — and — — -END CERTIFICATE — — — tags.

Import third-party public certificates to the JKS

Let’s try to import a third-party’s Public certificate as a Trusted CA Certificate.

I have extracted the “wso2carbon.pem file from the “wso2carbon.jks” (default key store shipped with WSO2 Products).

Let’s try to import “wso2carbon.pem” Public certificate to the “sample_keystore.jks”

keytool -import -trustcacerts -alias wso2carbon -file wso2carbon.pem -keystore sample_keystore.jks

Results will look like below,

Exploring Key Stores and Public Certificates — JKS (8)

Export private key entry from JKS

By default, the JKS key store type doesn’t support exporting the Private key entry using the key tool. But it can be achieved by converting the JKS key store to a PKCS12 key store.

Let’s explore how we can export the Private key entry from the “sample_keystore.jks”,

  • Convert the JKS “sample_keystore.jks” key store to a PKCS12 key store “sample_keystore.pfx”. We have already done it.
  • Export the Private key entry from the PKCS12 key store using the openssl into “sample_keystore_private_key.pem” file using PEM encoding
openssl pkcs12 -in sample_keystore.pfx -nodes -nocerts \
-out sample_keystore_private_key.pem

pkcs12 => Key store format we are using.
-nodes => No DES format so the Private key won’t be encrypted.
-nocerts => No certificates at all will be output.

Exported Private key entry will look like the below,

Exploring Key Stores and Public Certificates — JKS (9)

We need to provide the “sample_keystore.pfx” key store password as the Import Password.

As you can see the Private key entry is with the PEM encoding contains
— — -BEGIN PRIVATE KEY — — — and — — -END PRIVATE KEY — — — tags. The Private key is not encrypted.

Convert the private key entry from ‘PEM’ encoding to ‘DER’ encoding

By default, OpenSSL command saves the Private key entry (encrypted/unencrypted) to the file using the PEM encoding.

We can convert the PEM format to DER format using the below command,

openssl pkey -in sample_keystore_private_key.pem -inform pem \
-out sample_keystore_private_key.der -outform der

Exported Unencrypted Private key in DER format will look like below,

Exploring Key Stores and Public Certificates — JKS (10)

As you can see from above “sample_keystore_private_key.der” contains the unencrypted private key entry encoded in binary DER format.

Export the Triple-DES encrypted private key entry from the JKS

By default, if we don’t specify the encryption algorithm Or pass -nodes command, OpenSSL will encrypt the Private key entry using a 3DES encryption algorithm.

Following exports the PEM encoded 3DES encrypted private key entry,

openssl pkcs12 -in sample_keystore.pfx -nocerts \
-out sample_keystore_private_key_default_enc.pem

As you can see from the above “sample_keystore_private_key_default_enc.pem” contains the Triple-DES encrypted (3DES) private key entry.

Please refer to the link for further details on Triple-DES encryption.

Note the tags with — — -BEGIN ENCRYPTED PRIVATE KEY — — — and
— — -END ENCRYPTED PRIVATE KEY — — — which shows us the Private key entry is encrypted.

Apart from using the default 3DES algorithm, we can export the encrypted Private key entry by specifying one of the following encryption algorithms.

  • AES (aes128, aes192, and aes256) => -aes128, -aes192, -aes256
  • DES => -des
  • 3DES => -des3

The default is triple DES.

Export the ‘AES256’ encrypted private key entry from the JKS

Let’s now export the AES256 encrypted Private key entry by, passing the encryption algorithm as below,

Convert the JKS key store to the PKCS12 key store and then execute the following command,

openssl pkcs12 -in sample_keystore.pfx -aes256 -nocerts \
-out sample_keystore_private_key_aes256.pem

Note that we are passing an additional -aes256 argument.

Exported AES256 encrypted private key will look like below,

Exploring Key Stores and Public Certificates — JKS (11)

Export the ‘RSAPrivateKey’ from the JKS

Convert the JKS key store to the PKCS12 key store.

As you may have noticed that the Private key entry contains Bag Attributes and Key Attributes apart from the Encrypted/Un-encrypted Private key entry.

This is because the private key entry we extracted has a PrivateKeyInfo ASN.1 structure as defined in the PKCS#8 (RFC 5208). PrivateKeyInfo structure allows the Private key entry to contain:

  • A Private key
  • An OID that identifies the key type

Newer versions of OpenSSL generate Private key with PKCS#8 format which has — BEGIN PRIVATE KEY —and —END PRIVATE KEY — tags.

At the start of this blog, we created the “sample_keystore.jks” with an RSA 2048 Private and Public key pair. So we need to export the RSA Private key from the key store. Also, we need to use the RSA Private key for SSL communication.

RSAPrivateKey ASN.1 structure defined in PKCS#1 (RFC 3447) allows the Private key entry to only contain the Private key eliminating the
“Bag Attributes” and “Key Attributes”.

Older versions of OpenSSL generate Private key entry in PKCS#1 format with
—BEGIN RSA PRIVATE KEY — and —END RSA PRIVATE KEY —tags.

Since we are using the newer version of OpenSSL to extract the Private key entry, we got the Private key entry in PKCS#8 format with OID.

In order to generate the Private key entry with “RSAPrivateKey” let’s use the below command,

openssl pkcs12 -in sample_keystore.pfx -nodes -nocerts | \
openssl rsa -out sample_keystore_private_key_rsa.pem

RSA Private key entry will look like below,

Exploring Key Stores and Public Certificates — JKS (12)

As you can see from the above the Private key entry only contains the private key without other attributes.

Note the tags with —BEGIN RSA PRIVATE KEY — and
—END RSA PRIVATE KEY — which shows us the Private key entry is an RSAPrivateKey. The RSA private key is not encrypted.

Extracting ‘RSAPrivateKey’ from the ‘PKCS#8’ private key entry

Now let’s consider we already have a Private key entry in PKCS#8 format and we need to extract the RSA Private key from it.

Let’s use “sample_keystore_private_key.pem”, unencrypted PKCS#8 format private key entry and convert it to RSA Private key.

Let’s use the below command,

openssl rsa -in sample_keystore_private_key.pem \
-out sample_keystore_private_key_rsa_converted.pem

The converted “sample_keystore_private_key_rsa_converted.pem” will look like below,

Exploring Key Stores and Public Certificates — JKS (13)

Extracting Triple DES encrypted ‘RSAPrivateKey’ from the ‘PKCS#8’ private key entry

The RSA Private Key we exported Or converted is not encrypted and poses a security threat. Let’s see how we can encrypt the RSA private key while converting.

openssl rsa -in sample_keystore_private_key.pem -des3 \
-out sample_keystore_private_key_rsa_des3.pem
Exploring Key Stores and Public Certificates — JKS (14)

As you can see from the above, the RSA Private key is encrypted.

Note the Proc-Type: 4,ENCRYPTED attribute which shows us the RSA private key entry is encrypted.

Import a private key entry to JKS

We can’t directly import Private key entry to a JKS type key store.
We can import the Private key to a PKCS12 key store and convert it to a JKS key store.

Following command exports the private key, public certificate and certificate chain as a ‘PKCS12’ keystore,

openssl pkcs12 -export -in <public_cert>.crt \
-inkey <private_key>.key -chain -CAfile <ca_cert>.crt \
-name "sample.com" -out sample_keystore_pkcs12.p12

Be sure to set an export password to avoid NullPointerException

Following command converts the ‘PKCS12’ key store to a JKS,

keytool -importkeystore -srckeystore sample_keystore_pkcs12.p12 \
-srcstoretype PKCS12 \
-destkeystore sample_keystore_with_imported_private_key.jks \
-deststoretype JKS -deststorepass abcd@1234

Generating JKS with ‘Secret Key’ entry

According to the JKS key store specification, we can’t store non-PrivateKeys in a “JKS” type key store.

Let’s verify the above statement by trying to generate a JKS key store with a Secret key as below,

keytool -genseckey -alias secretKey -keypass secretKey \
-keyalg AES -keysize 256 -keystore secretKey.jks \
-storepass secretKey -storetype JKS -v

-genseckey option is used to generate the Secret key.
-keyalg argument is used to pass the Secret key algorithm.
Common secret key algorithms include DES, 3DES, and AES.

The above command will result in a key tool error like below,

Exploring Key Stores and Public Certificates — JKS (15)

As you can see even though the 256-bit AES secret key is generated it cannot be stored in the JKS type key store.

Similarly, we can’t import a Secret key entry to a JKS key store.

References:

[1] https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/security/KeyStore.html
[2] https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html#keytool_option_genkeypair
[3] https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Prepare_the_Certificate_Keystore
[4] https://en.wikipedia.org/wiki/Triple_DES

We have explored different aspects of the JKS key store in this blog.
We will continue to explore the other types of key stores in future blogs.

Thank you for reading.
Cheers!!!

Exploring Key Stores and Public Certificates — JKS (2024)

FAQs

What is a JKS certificate used for? ›

A Java KeyStore (JKS) is a repository of security certificates – either authorization certificates or public key certificates – plus corresponding private keys, used for instance in TLS encryption.

How to extract public and private key from JKS file? ›

Export private key entry from JKS
  1. Convert the JKS “sample_keystore. jks” key store to a PKCS12 key store “sample_keystore. pfx”. We have already done it.
  2. Export the Private key entry from the PKCS12 key store using the openssl into “sample_keystore_private_key. pem” file using PEM encoding.
Feb 12, 2022

What is keystore used for? ›

Keystores and truststores are repositories that contain cryptographic artifacts like certificates and private keys that are used for cryptographic protocols such as TLS. A keystore contains personal certificates, plus the corresponding private keys that are used to identify the owner of the certificate.

How to get a public certificate from keystore? ›

How to export private key and public key from keystore
  1. Export the private key from pkcs12 format keystore.
  2. openssl pkcs12 -in keystore_name.p12 -nodes -nocerts -out private.key.
  3. Export the public certificate from pkcs12 format keystore.
  4. openssl pkcs12 -in keystore_name.p12 -nokeys -out public-cert-file.

What is the difference between JKS and keystore? ›

keystore and . jks are just file extensions: it's up to you to name your files sensibly. Some application use a keystore file stored in $HOME/. keystore : it was usually implied that it was JKS file, since JKS was the default keystore type in the Sun/Oracle Java security provider, up to Java 8.

What is the difference between certificate and JKS? ›

jks, contains the Application Server's trusted certificates, including public keys for other entities. For a trusted certificate, the server has confirmed that the public key in the certificate belongs to the certificate's owner. Trusted certificates generally include those of certification authorities (CAs).

What is the difference between keystore and TrustStore? ›

The KeyStore is used by the adapter for client authentication, while the TrustStore is used to authenticate a server in SSL authentication. A KeyStore consists of a database containing a private key and an associated certificate, or an associated certificate chain.

Does keystore contain public keys? ›

The keystore file is a database that contains both public and private keys. Public and private keys are created simultaneously using the same algorithm (for example, RSA). A public key is used for encrypting or decrypting information.

How to extract public key from certificate using keytool? ›

You can print the cert to pem format, then use openssl to print public key from the pem format.
  1. add -rfc option to -printcert. keytool -printcert -rfc -file client.crt.
  2. save the output like below to a file client.pem. ...
  3. then use openssl.
Apr 11, 2012

How important is a KeyStore? ›

Protection Against Malicious Activities: Keystores protect mobile applications from various attacks, such as man-in-the-middle attacks, data interceptions, and unauthorized access, by securely storing cryptographic materials.

What is the difference between Keytool and KeyStore? ›

Keytool is a certificate management utility included with Java. It allows users to create a single store, called a keystore, that can hold multiple certificates within it.

Is KeyStore same as KeyChain? ›

Use the Android Keystore provider to let an individual app store its own credentials, which only that app can access. This provides a way for apps to manage credentials that only they can use while providing the same security benefits that the KeyChain API provides for system-wide credentials.

Is public key same as public certificate? ›

A certificate is a trusted document that contains a public key and other data of the respective private key owner. Examples of such data are the private key owner identification and the possible connections established with the private key owner.

What is JKS used for? ›

A Java keystore (JKS) file is a secure file format used to hold certificate information for Java applications.

How do I view all certificates in keystore? ›

To view and list the certificates within the Truststore or Keystore:
  1. keytool -list -v -keystore <name-of-your-truststore-or-keystore>
  2. keytool -list -v -keystore <name-of-your-truststore-or-keystore> > <exported_certificates_list>.log.
Apr 15, 2024

What is the difference between p12 and JKS? ›

The biggest difference between JKS and PKCS12 is that JKS is a format specific to Java, while PKCS12 is a standardized and language-neutral way of storing encrypted private keys and certificates.

What is the difference between keystore and certificate? ›

A KeyStore consists of a database containing a private key and an associated certificate, or an associated certificate chain. The certificate chain consists of the client certificate and one or more certification authority (CA) certificates.

What is the difference between PFX and JKS? ›

What is Java KeyStore file? JKS also similar to PFX file, It is a repository to store the certificates and private keys. But the JKS files are very specific to Java and its applications. Application servers like Tomcat, Oracle WebLogic, IBM WebSphere uses JKS file as a KeyStore.

What is the difference between JKS and PEM? ›

It depends on your security needs and the systems you're using. PEM is cool for casual key sharing, while JKS is better for high-security Java environments.

Top Articles
Latest Posts
Article information

Author: Melvina Ondricka

Last Updated:

Views: 5763

Rating: 4.8 / 5 (68 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Melvina Ondricka

Birthday: 2000-12-23

Address: Suite 382 139 Shaniqua Locks, Paulaborough, UT 90498

Phone: +636383657021

Job: Dynamic Government Specialist

Hobby: Kite flying, Watching movies, Knitting, Model building, Reading, Wood carving, Paintball

Introduction: My name is Melvina Ondricka, I am a helpful, fancy, friendly, innocent, outstanding, courageous, thoughtful person who loves writing and wants to share my knowledge and understanding with you.