Hi, Habr! I present to your attention 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.
Java KeyStore is a key store in the form of a database, represented by the KeyStore class ( java.security.KeyStore ). The storage can be written to disk and read again, it can be protected with a password, and each key entry in the keystore can be protected with its own password, which makes the KeyStore
class a useful mechanism for working with encryption keys securely. The keystore can contain keys of the following types:
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 ownership of a public key. The certificate is usually digitally signed by the verifier as evidence. Secret keys are used in symmetric encryption. In most cases, when setting up a secure connection, symmetric keys are inferior to asymmetric keys, so most often you will store public and private keys in the keystore.
You can create an instance of KeyStore
by calling its getInstance()
method. Here is an example of creating an instance of a class:
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
This example creates a default KeyStore
instance. You can also create KeyStore instances with a different key storage format by passing a parameter to the getInstance()
method. For example, creating a PKCS12
keystore instance:
KeyStore keyStore = KeyStore.getInstance("PKCS12");
Before you can use a copy of the keystore, you must load it. Instances of the KeyStore
class KeyStore
often written to disk or to another storage for later use, because the KeyStore
class assumes that you must read its data before you can use it. However, you can initialize an empty KeyStore
instance KeyStore
no data, as you will see later.
Loading data from a file or other storage is done by calling the load()
method which takes two parameters:
InputStream
from which the data will be loaded.char[]
An array of characters containing the password from the keystore.Here is an example of loading the keystore:
char[] keyStorePassword = "123abc".toCharArray(); try(InputStream keyStoreData = new FileInputStream("keystore.ks")){ keyStore.load(keyStoreData, keyStorePassword); }
This example loads the keystore file keystore.ks. If you do not want to upload any data to the keystore, simply pass null
for the InputStream
parameter. Here is the loading of an empty keystore:
keyStore3.load(null, keyStorePassword);
An instance of the KeyStore
class KeyStore
always be loaded with either data or null
. Otherwise, the keystore is not initialized, and all calls to its methods will raise exceptions.
You can get instance keys of the KeyStore
class via its getEntry()
method. The keystore entry is mapped to an alias, which identifies the key, and is protected by the key password. Thus, in order to access the key, you must pass the key alias and password to the getEntry()
method. Here is an example of access to the record in the KeyStore
instance:
char[] keyPassword = "789xyz".toCharArray(); KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(keyPassword); KeyStore.Entry keyEntry = keyStore3.getEntry("keyAlias", entryPassword);
If you know that the entry you want to access is the private key, you can convert the KeyStore.Entry
instance to KeyStore.PrivateKeyEntry
. Here's what it looks like:
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore3.getEntry("keyAlias", entryPassword);
After casting to KeyStore.PrivateKeyEntry
you can access the private key, certificate, and certificate chain using the following methods:
getPrivateKey()
getCertificate()
getCertificateChain()
You can also put keys into an instance of the KeyStore
class. An example of placing a secret key (a symmetric key) into a KeyStore
instance:
SecretKey secretKey = getSecretKey(); KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey); keyStore3.setEntry("keyAlias2", secretKeyEntry, entryPassword);
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. An instance of the KeyStore
class KeyStore
stored by calling the store()
method. Example:
char[] keyStorePassword = "123abc".toCharArray(); try (FileOutputStream keyStoreOutputStream = new FileOutputStream("data/keystore.ks")) { keyStore3.store(keyStoreOutputStream, keyStorePassword); }
Source: https://habr.com/ru/post/445786/