Keystore type: which one to use?
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?
Solution 1:
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.
Solution 2:
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.
Solution 3:
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
andJCEKS
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:
- Mind Your Keys? A Security Evaluation of Java Keystores (PDF)
- Java KeyStores – the gory details
Solution 4:
Java 11 offers the following types of KeyStore
s:
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