JKS and JCEKS keystores

Background

The JKS keystore format is the format that originally shipped with Java. It is implemented by the traditional “Sun” cryptography provider.

JCEKS is an improved keystore format introduced with the Java Cryptography Extension (JCE). It is implemented by the SunJCE cryptography provider.

JCEKS keystores improve upon JKS keystores in 2 ways:
  • A stronger key protection algorithm is used
  • They allow for arbitrary (symmetric) secret keys to be stored (e.g. AES, DES, etc.)

Store types

class jks.jks.KeyStore(store_type, entries)[source]

Bases: jks.util.AbstractKeystore

Represents a loaded JKS or JCEKS keystore.

entries

A dictionary of all entries in the keystore, mapped by alias.

store_type

A string indicating the type of keystore that was loaded. Can be one of jks, jceks.

classmethod load(filename, store_password, try_decrypt_keys=True)

Convenience wrapper function; reads the contents of the given file and passes it through to loads(). See loads().

classmethod loads(data, store_password, try_decrypt_keys=True)[source]

Loads the given keystore file using the supplied password for verifying its integrity, and returns a KeyStore instance.

Note that entries in the store that represent some form of cryptographic key material are stored in encrypted form, and therefore require decryption before becoming accessible.

Upon original creation of a key entry in a Java keystore, users are presented with the choice to either use the same password as the store password, or use a custom one. The most common choice is to use the store password for the individual key entries as well.

For ease of use in this typical scenario, this function will attempt to decrypt each key entry it encounters with the store password:

  • If the key can be successfully decrypted with the store password, the entry is returned in its decrypted form, and its attributes are immediately accessible.
  • If the key cannot be decrypted with the store password, the entry is returned in its encrypted form, and requires a manual follow-up decrypt(key_password) call from the user before its individual attributes become accessible.

Setting try_decrypt_keys to False disables this automatic decryption attempt, and returns all key entries in encrypted form.

You can query whether a returned entry object has already been decrypted by calling the is_decrypted() method on it. Attempting to access attributes of an entry that has not yet been decrypted will result in a NotYetDecryptedException.

Parameters:
  • data (bytes) – Byte string representation of the keystore to be loaded.
  • password (str) – Keystore password string
  • try_decrypt_keys (bool) – Whether to automatically try to decrypt any encountered key entries using the same password as the keystore password.
Returns:

A loaded KeyStore instance, if the keystore could be successfully parsed and the supplied store password is correct.

If the try_decrypt_keys parameter was set to True, any keys that could be successfully decrypted using the store password have already been decrypted; otherwise, no atttempt to decrypt any key entries is made.

Raises:
classmethod new(store_type, store_entries)[source]

Helper function to create a new KeyStore.

Parameters:
  • store_type (string) – What kind of keystore the store should be. Valid options are jks or jceks.
  • store_entries (list) – Existing entries that should be added to the keystore.
Returns:

A loaded KeyStore instance, with the specified entries.

Raises:
  • DuplicateAliasException – If some of the entries have the same alias.
  • UnsupportedKeyStoreTypeException – If the keystore is of an unsupported type
  • UnsupportedKeyStoreEntryTypeException – If some of the keystore entries are unsupported (in this keystore type)
save(filename, store_password)

Convenience wrapper function; calls the saves() and saves the content to a file.

saves(store_password)[source]

Saves the keystore so that it can be read by other applications.

If any of the private keys are unencrypted, they will be encrypted with the same password as the keystore.

Parameters:

store_password (str) – Password for the created keystore (and for any unencrypted keys)

Returns:

A byte string representation of the keystore.

Raises:
certs

A subset of the entries dictionary, filtered down to only those entries of type TrustedCertEntry.

private_keys

A subset of the entries dictionary, filtered down to only those entries of type PrivateKeyEntry.

secret_keys

A subset of the entries dictionary, filtered down to only those entries of type SecretKeyEntry.

Entry types

class jks.jks.TrustedCertEntry(**kwargs)[source]

Bases: jks.util.AbstractKeystoreEntry

Represents a trusted certificate entry in a JKS or JCEKS keystore.

decrypt(key_password)[source]

Does nothing for this entry type; certificates are inherently public data and are not stored in encrypted form.

encrypt(key_password)[source]

Does nothing for this entry type; certificates are inherently public data and are not stored in encrypted form.

is_decrypted()[source]

Always returns True for this entry type.

classmethod new(alias, cert)[source]

Helper function to create a new TrustedCertEntry.

Parameters:
  • alias (str) – The alias for the Trusted Cert Entry
  • certs (str) – The certificate, as a byte string.
Returns:

A loaded TrustedCertEntry instance, ready to be placed in a keystore.

cert = None

A byte string containing the actual certificate data. In the case of X.509 certificates, this is the DER-encoded X.509 representation of the certificate.

type = None

A string indicating the type of certificate. Unless in exotic applications, this is usually X.509.

class jks.jks.PrivateKeyEntry(**kwargs)[source]

Bases: jks.util.AbstractKeystoreEntry

Represents a private key entry in a JKS or JCEKS keystore (e.g. an RSA or DSA private key).

pkey

Note

Only accessible after a call to decrypt(); until then, accessing this attribute will raise a NotYetDecryptedException. See also try_decrypt_keys on jks.jks.KeyStore.loads().

A byte string containing the value of the privateKey field of the PKCS#8 PrivateKeyInfo representation of the private key. See RFC 5208, section 5: Private-Key Information Syntax.

pkey_pkcs8

Note

Only accessible after a call to decrypt(); until then, accessing this attribute will raise a NotYetDecryptedException. See also try_decrypt_keys on jks.jks.KeyStore.loads().

A byte string containing the DER-encoded PKCS#8 PrivateKeyInfo representation of the private key. See RFC 5208, section 5: Private-Key Information Syntax.

algorithm_oid

Note

Only accessible after a call to decrypt(); until then, accessing this attribute will raise a NotYetDecryptedException. See also try_decrypt_keys on jks.jks.KeyStore.loads().

A tuple of integers corresponding to the algorithm OID for which the private key is valid.

Common values include:

  • (1,2,840,113549,1,1,1) (alias rsaEncryption)
  • (1,2,840,10040,4,1) (alias id-dsa).
cert_chain = None

A list of tuples, representing the certificate chain associated with the private key. Each element of the list of a 2-tuple containing the following data:

  • [0]: A string indicating the type of certificate. Unless in exotic applications, this is usually X.509.
  • [1]: A byte string containing the actual certificate data. In the case of X.509 certificates, this is the DER-encoded X.509 representation of the certificate.
classmethod new(alias, certs, key, key_format='pkcs8')[source]

Helper function to create a new PrivateKeyEntry.

Parameters:
  • alias (str) – The alias for the Private Key Entry
  • certs (list) – An list of certificates, as byte strings. The first one should be the one belonging to the private key, the others the chain (in correct order).
  • key (str) – A byte string containing the private key in the format specified in the key_format parameter (default pkcs8).
  • key_format (str) – The format of the provided private key. Valid options are pkcs8 or rsa_raw. Defaults to pkcs8.
Returns:

A loaded PrivateKeyEntry instance, ready to be placed in a keystore.

Raises:

UnsupportedKeyFormatException – If the key format is unsupported.

is_decrypted()[source]

Returns True if the entry has already been decrypted, False otherwise.

decrypt(key_password)[source]

Decrypts the entry using the given password. Has no effect if the entry has already been decrypted.

Parameters:

key_password (str) – The password to decrypt the entry with. If the entry was loaded from a JCEKS keystore, the password must not contain any characters outside of the ASCII character set.

Raises:
encrypt(key_password)[source]

Encrypts the private key, so that it can be saved to a keystore.

This will make it necessary to decrypt it again if it is going to be used later. Has no effect if the entry is already encrypted.

Parameters:key_password (str) – The password to encrypt the entry with.
class jks.jks.SecretKeyEntry(**kwargs)[source]

Bases: jks.util.AbstractKeystoreEntry

Represents a secret (symmetric) key entry in a JCEKS keystore (e.g. an AES or DES key).

algorithm

Note

Only accessible after a call to decrypt(); until then, accessing this attribute will raise a NotYetDecryptedException. See also try_decrypt_keys on jks.jks.KeyStore.loads().

A string containing the name of the algorithm for which the key is valid, as known to the Java cryptography provider that supplied the corresponding SecretKey object.

key

Note

Only accessible after a call to decrypt(); until then, accessing this attribute will raise a NotYetDecryptedException. See also try_decrypt_keys on jks.jks.KeyStore.loads().

A byte string containing the raw secret key.

key_size

Note

Only accessible after a call to decrypt(); until then, accessing this attribute will raise a NotYetDecryptedException. See also try_decrypt_keys on jks.jks.KeyStore.loads().

An integer containing the size of the key, in bits. For DES and 3DES keys, the sizes 64 bits resp. 192 bits are returned.

classmethod new(alias, sealed_obj, algorithm, key, key_size)[source]

Helper function to create a new SecretKeyEntry.

Returns:A loaded SecretKeyEntry instance, ready to be placed in a keystore.
is_decrypted()[source]

Returns True if the entry has already been decrypted, False otherwise.

decrypt(key_password)[source]

Decrypts the entry using the given password. Has no effect if the entry has already been decrypted.

Parameters:

key_password (str) – The password to decrypt the entry with. Must not contain any characters outside of the ASCII character set.

Raises:
encrypt(key_password)[source]

Encrypts the Secret Key so that the keystore can be saved