Keystore type: which one to use?
Asked Answered
P

4

138

By looking at the file java.security of my JRE, I see that the keystore type to use by default is set to JKS. Here, there is a list of the keystore types that can be used.

Is there a recommended keystore type? What are the pros/cons of the different keystore types?

Plexiglas answered 18/7, 2012 at 8:4 Comment(1)
Since Java 9, PKCS12 is the default keystore type. This change is to the the JEP 229 goal: "Improve security. PKCS12 offers stronger cryptographic algorithms than JKS." For more info see "JEP 229: Create PKCS12 Keystores by Default", openjdk.java.net/jeps/229; last accessed Feb 2, 2018.Enterovirus
T
175

There are a few more types than what's listed in the standard name list you've linked to. You can find more in the cryptographic providers documentation. The most common are certainly JKS (the default) and PKCS12 (for PKCS#12 files, often with extension .p12 or sometimes .pfx).

JKS is the most common if you stay within the Java world. PKCS#12 isn't Java-specific, it's particularly convenient to use certificates (with private keys) backed up from a browser or coming from OpenSSL-based tools (keytool wasn't able to convert a keystore and import its private keys before Java 6, so you had to use other tools).

If you already have a PKCS#12 file, it's often easier to use the PKCS12 type directly. It's possible to convert formats, but it's rarely necessary if you can choose the keystore type directly.

In Java 7, PKCS12 was mainly useful as a keystore but less for a truststore (see the difference between a keystore and a truststore), because you couldn't store certificate entries without a private key. In contrast, JKS doesn't require each entry to be a private key entry, so you can have entries that contain only certificates, which is useful for trust stores, where you store the list of certificates you trust (but you don't have the private key for them).

This has changed in Java 8, so you can now have certificate-only entries in PKCS12 stores too. (More details about these changes and further plans can be found in JEP 229: Create PKCS12 Keystores by Default.)

There are a few other keystore types, perhaps less frequently used (depending on the context), those include:

  • PKCS11, for PKCS#11 libraries, typically for accessing hardware cryptographic tokens, but the Sun provider implementation also supports NSS stores (from Mozilla) through this.
  • BKS, using the BouncyCastle provider (commonly used for Android).
  • Windows-MY/Windows-ROOT, if you want to access the Windows certificate store directly.
  • KeychainStore, if you want to use the OSX keychain directly.
Thaine answered 18/7, 2012 at 11:15 Comment(13)
@husayt, PEM certificates are not directly supported as keystore types (I suppose one could write a KeyStore implementation to that effect). You can however, load them on the fly into a keystore instance (typically JKS, the default type) in memory using a CertificateFactory (as shown in this answer).Thaine
i think the JKS has changed to JCEKSRadium
@Radium both types exist indeed, but JKS is still the default AFAIK.Thaine
Rather critically, a JKS key store cannot store secret keys. For this use case, JCEKS is appropriate. It may be worth mentioning this in your answer.Discount
@Thaine so we can't store a plain keyfile that has 32 char random string which is used to encrypt the data to PKCS12 ?Mononuclear
PKCS#12 will be the default from Java 9 onwards. PKCS#12 can store secret keys and should also be useable as trust store.Eldest
@MaartenBodewes Indeed, PKCS#12 can already be used as a trust store, but only if it also has a private key with the cert at the moment. It could probably be used more generally without private keys, but last time I checked (probably Java 7), the Java implementation didn't allow for such PKCS#12 stores. I can't remember what the PKCS#12 spec says exactly about this, but I think it was a Java implementation limitation, so it's quite possible that further versions of Java let you use PKCS#12 stores more broadly.Thaine
Ok. In Java 8 I can create a PKCS#12 keystore with a single certificate without any issue. Note that for P12 certificate entries are implicitly trusted. If you need untrusted certs you may have to revert to a scheme with multiple key stores.Eldest
@MaartenBodewes You're right. I've just tried with keytool from the Oracle JDK 1.7.0_71, and importing a cert on its own (without private key) didn't work, but it works with the one from Oracle JDK 1.8.0_25 (and newer).Thaine
OK at least for Java 8 PKCS#12 key stores still cannot store secret key entries. You'll get a null pointer exception when storing such a key store (ugh), probably because it cannot find associated certificates. Somebody seemingly skipped the teachings of Joshua about fail fast code.Eldest
@Thaine is there resource where I can learn more about keystore and sslcontext. I can't find a single resource that gives me a good intorduction to these topicsGarygarza
@Garygarza I'd look at the JSSE Reference Guide and perhaps the Javadoc for KeyStore. Not necessarily the easiest introduction, but there are good explanations and a few diagrams.Thaine
@Thaine in windows environments you also can use Windows-MY-LOCALMACHINE/ Windows-ROOT-LOCALMACHINE but you will require administrator permissions.Peahen
E
26

Here is a post which introduces different types of keystore in Java and the differences among different types of keystore. http://www.pixelstech.net/article/1408345768-Different-types-of-keystore-in-Java----Overview

Below are the descriptions of different keystores from the post:

JKS, Java Key Store. You can find this file at sun.security.provider.JavaKeyStore. This keystore is Java specific, it usually has an extension of jks. This type of keystore can contain private keys and certificates, but it cannot be used to store secret keys. Since it's a Java specific keystore, so it cannot be used in other programming languages.

JCEKS, JCE key store. You can find this file at com.sun.crypto.provider.JceKeyStore. This keystore has an extension of jceks. The entries which can be put in the JCEKS keystore are private keys, secret keys and certificates.

PKCS12, this is a standard keystore type which can be used in Java and other languages. You can find this keystore implementation at sun.security.pkcs12.PKCS12KeyStore. It usually has an extension of p12 or pfx. You can store private keys, secret keys and certificates on this type.

PKCS11, this is a hardware keystore type. It servers an interface for the Java library to connect with hardware keystore devices such as Luna, nCipher. You can find this implementation at sun.security.pkcs11.P11KeyStore. When you load the keystore, you no need to create a specific provider with specific configuration. This keystore can store private keys, secret keys and cetrificates. When loading the keystore, the entries will be retrieved from the keystore and then converted into software entries.

Epithalamium answered 21/8, 2014 at 9:27 Comment(3)
@peci1 I have planned to write some tutorials on how to use these keystores. So far I have written one post for JKS, please find it at pixelstech.net/article/…Epithalamium
@Epithalamium I've found this one and was wondering where's the rest of them :) So I'll stay tuned ;) ThanksDentil
@peci1 I have covered JCEKS and PKCS12 today. For PKCS11, it involves hardware and extra configuration, need more time to compose it. pixelstech.net/article/… and pixelstech.net/article/…Epithalamium
D
16

If you are using Java 8 or newer you should definitely choose PKCS12, the default since Java 9 (JEP 229).

The advantages compared to JKS and JCEKS are:

  • Secret keys, private keys and certificates can be stored
  • PKCS12 is a standard format, it can be read by other programs and libraries1
  • Improved security: JKS and JCEKS are pretty insecure. This can be seen by the number of tools for brute forcing passwords of these keystore types, especially popular among Android developers.2, 3

1 There is JDK-8202837, which has been fixed in Java 11

2 The iteration count for PBE used by all keystore types (including PKCS12) used to be rather weak (CVE-2017-10356), however this has been fixed in 9.0.1, 8u151, 7u161, and 6u171

3 For further reading:

Delouse answered 20/10, 2019 at 14:55 Comment(0)
I
5

Java 11 offers the following types of KeyStores:

jceks: The proprietary keystore implementation provided by the SunJCE provider.

jks: The proprietary keystore implementation provided by the SUN provider.

dks: A domain keystore is a collection of keystores presented as a single logical keystore. It is specified by configuration data whose syntax is described in the DomainLoadStoreParameter class.

pkcs11: A keystore backed by a PKCS #11 token.

pkcs12: The transfer syntax for personal identity information as defined in PKCS #12.

Source: https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#keystore-types

Inattention answered 19/3, 2021 at 14:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.