Different types of keystore in Java -- PKCS11
PKCS11 keystore is designed for hardware storage modules（HSM）. It's an interface to talk to the HSMs. It doesn't actually store any keys but provide a set of classes to communicate with the underlying HSM. The actual keys and certificates are stored on the HSMs.
The reason for storing the keys and materials is to ensure security and efficiency. Since the keys are on the HSMs, they are safe to be stolen. All encryption/decryption operations are performed on the HSMs as well, this increase the processing speed. They are frequently used in applications requiring high speed and extra security.
There are different hardware devices which can be used to store keys and certificates such as nCipher and Luna SA from SafeNet. They put a big challenge on the design of Java PKCS11 keystore, because they need to talk to different hardware devices with different structures.
Usually to talk to the hardware devices, there are some configurations needed and also a special PKCS11 provider needs to be created and added to the provider list, the process of creating the provider may involve login to the hardware device. Once the provider is created, the hardware keystore can be loaded.
To create the PKCS11 provider, you can either add the provider to the java.security file statically or using the Provider class dynamically in Java.
To create the provider statically, add below line in java.security located at $JRE_HOME/lib/security/java.security.
Here N means the index where you want to put the provider at. The pkcs11.cfg is the configuration file which defines what the Java PKCS11 interface can get from or put to the HSMs. For the detailed configuration files, consult with the HSM vendors.
To create the provider dynamically, add below codes in the application you have before creating the hardware keystore instance.
String configName = "/opt/bar/cfg/pkcs11.cfg"; Provider p = new sun.security.pkcs11.SunPKCS11(configName); Security.addProvider(p);
For details about creating the PKCS11 provider, please read Oracle documentation.
Once the provider is ready. Start to create the KeyStore instance. Since it's hardware keystore, so when calling KeyStore.load(), the input stream should be null.
Below is the code snippet for creating and loading the hardware keystore:
KeyStore ks = KeyStore.getInstance("PKCS11", p); //p is the provider created above ks.load(null, password);
Once the keystore is loaded, you can start to create keys(secret and private) and certificates on the HSMs. The details of how to create them are similar to what PKCS12 does. So please refer to PKCS12 keystore for details.
One exception is that there is no need to call KeyStore.store() to save the keystore, the keystore will automatically save when KeyStore.setKeyEntry() is invoked or other KeyStore.setXXX() is invoked.