Cryptography in Java. KeyStore Class

Original author: Jakob Jenkov
  • Transfer

Hello, Habr! I present to you the translation of article 9 of the "Java KeyStore" by Jakob Jenkov from a series of articles for beginners who want to learn the basics of cryptography in Java.


Table of contents:


  1. Java cryptography
  2. Java cipher
  3. Messagedigest
  4. Mac
  5. Signature
  6. Keypair
  7. Keygenerator
  8. KeyPairGenerator
  9. Keystore
  10. Keytool
  11. Certificate
  12. CertificateFactory
  13. CertPath

Keystore


Java KeyStore is a database-style key store provided by the KeyStore class ( java.security.KeyStore ). The storage can be written to disk and read again, it can be password protected, and each key record in the key store can be protected with its own password, which makes the class a KeyStoreuseful mechanism for working with encryption keys safely. A keystore can contain keys of the following types:


  • Private keys
  • Public keys and certificates (Public keys + certificates)
  • Secret keys

Private and public keys are used in asymmetric encryption. The public key may have an associated certificate. A certificate is a document proving the identity of a person, organization, or device claiming to own a public key. The certificate is usually digitally signed by the relying party as evidence. Private keys are used in symmetric encryption. In most cases, when setting up a secure connection, symmetric keys are inferior to asymmetric ones, so most often you will store public and private keys in the keystore.


Creating a keystore


You can create an instance KeyStoreby calling its method getInstance(). Here is an example of creating an instance of a class:


KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

This example creates a KeyStoredefault instance . You can also create KeyStore instances with a different key storage format by passing a parameter to the method getInstance(). For example, creating an instance of a keystore PKCS12:


KeyStore keyStore = KeyStore.getInstance("PKCS12");

Download keystore


Before you can use an instance of a keystore, you must download it. Instances of a class KeyStoreare often written to disk or other storage for later use, because the class KeyStoreassumes that you must read its data before you can use it. However, you can initialize an empty instance KeyStorewithout data, as you will see later.


Data is loaded from a file or other storage by calling a method load()that takes two parameters:


  • InputStream from which data will be loaded.
  • char[] An array of characters containing the password from the keystore.

Here is an example of loading a keystore:


char[] keyStorePassword = "123abc".toCharArray();
try(InputStream keyStoreData = new FileInputStream("keystore.ks")){
    keyStore.load(keyStoreData, keyStorePassword);
}

This example loads the keystore.ks keystore file. If you do not want to load any data into the keystore, just pass the value nullfor the parameter InputStream. This is how loading an empty keystore looks like:


keyStore3.load(null, keyStorePassword);

A class instance KeyStoremust always be loaded either with data or with null. Otherwise, the keystore is not initialized, and all calls to its methods will throw exceptions.


Receiving keys


You can get the keys of an instance of a class KeyStorethrough its method getEntry(). The keystore record is mapped to an alias that identifies the key and is password protected. Thus, in order to access the key, you must pass the key alias and password to the method getEntry(). Here is an example of write access to an instance KeyStore:


char[] keyPassword = "789xyz".toCharArray();
KeyStore.ProtectionParameter entryPassword =
        new KeyStore.PasswordProtection(keyPassword);
KeyStore.Entry keyEntry = keyStore3.getEntry("keyAlias", entryPassword);

If you know that the record you want to access is the private key, you can convert the instance KeyStore.Entryto KeyStore.PrivateKeyEntry. Here's what it looks like:


KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)
        keyStore3.getEntry("keyAlias", entryPassword);

After casting to, KeyStore.PrivateKeyEntryyou can access the private key, certificate, and certificate chain using the following methods:


  • getPrivateKey()
  • getCertificate()
  • getCertificateChain()

Key storage


You can also put the keys in an instance of the class KeyStore. An example of placing a secret key (symmetric key) in an instance KeyStore:


SecretKey secretKey = getSecretKey();
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);
keyStore3.setEntry("keyAlias2", secretKeyEntry, entryPassword);

Storage


Sometimes you may want to save the keystore to some kind of storage (disk, database, etc.) so that you can load it again another time. A class instance is KeyStoresaved by a method call store(). Example:


char[] keyStorePassword = "123abc".toCharArray();
try (FileOutputStream keyStoreOutputStream = new FileOutputStream("data/keystore.ks")) {
    keyStore3.store(keyStoreOutputStream, keyStorePassword);
}

Also popular now: