Hardware security module (HSM)
This topic demonstrates how to use a PKCS #11 device, such as a hardware security module (HSM), to store the keys used to secure communications. IDM supports retrieval of secrets from HSMs either locally or over the network.
On Windows systems using the 64-bit JDK, the Sun PKCS #11 provider is available only from JDK version 1.8b49. If you want to use a PKCS #11 device on Windows, use the 32-bit version of the JDK, or upgrade your 64-bit JDK to version 1.8b49 or higher. |
HSM configuration
This section assumes that you have access to an HSM device (or a software emulation of an HSM device, such as SoftHSM) and that the HSM provider has been configured and initialized.
The command-line examples in this section use SoftHSM for testing purposes. Before you start, set the correct environment variable for the SoftHSM configuration, for example:
export SOFTHSM2_CONF=/path/to/softhsm/2.0.0/etc/softhsm2.conf
Also initialize slot 0
on the provider, with a command similar to the following:
softhsm2-util --init-token --slot 0 --label "My token 1"
This token initialization requests two PINs—an SO PIN and a user PIN. You can use the SO PIN to reinitialize the token. The user PIN is provided to IDM so that it can interact with the token. Remember the values of these PINs because you will use them later in this section.
The PKCS #11 standard uses a configuration file to interact with the HSM device. The following example shows a basic configuration file for SoftHSM:
name = softHSM
library = /path/to/softhsm/2.0.0/lib/softhsm/libsofthsm2.so
slot = 1
attributes(generate, *, *) = {
CKA_TOKEN = true
}
attributes(generate, CKO_CERTIFICATE, *) = {
CKA_PRIVATE = false
}
attributes(generate, CKO_PUBLIC_KEY, *) = {
CKA_PRIVATE = false
}
attributes(*, CKO_SECRET_KEY, *) = {
CKA_PRIVATE = false
CKA_EXTRACTABLE = true
}
Your HSM configuration file must include at least the following settings:
name
-
A suffix to identify the HSM provider. This example uses the
softHSM
provider. library
-
The path to the PKCS #11 library.
slot
-
The slot number to use, specified as a string. Make sure that the slot you specify here has been initialized on the HSM device.
The attributes
specify additional PKCS #11 attributes that are set by the HSM. For a complete list of these attributes, see the PKCS #11 Reference.
If you are using the JWT Session Module, you must set
The HSM provider must allow secret keys to be extractable because the authentication service serializes the JWT Session Module key and passes it to the authentication framework as a base 64-encoded string. |
HSM default encryption keys
When IDM first starts up, it generates a number of encryption keys required to encrypt specific data. If you are using an HSM provider, you must generate these keys manually. The secret keys must use an HMAC algorithm.
This procedure assumes that your HSM configuration file is located at |
-
The
openidm-sym-default
key is the default symmetric key required to encrypt the configuration. The following command generates that key in the HSM provider. The-providerArg
must point to the HSM configuration file described in HSM Configuration.keytool \ -genseckey \ -alias openidm-sym-default \ -keyalg HmacSHA256 \ -keysize 256 \ -keystore NONE \ -storetype PKCS11 \ -providerClass sun.security.pkcs11.SunPKCS11 \ -providerArg /path/to/hsm/hsm.conf Enter keystore password:
Enter the password of your HSM device. If you are using SoftHSM, enter your user PIN as the keystore password.
-
The
openidm-selfservice-key
is used by the Self-Service UI to encrypt managed user passwords and other sensitive data. Generate theopenidm-selfservice-key
key:keytool \ -genseckey \ -alias openidm-selfservice-key \ -keyalg HmacSHA256 \ -keysize 256 \ -keystore NONE \ -storetype PKCS11 \ -providerClass sun.security.pkcs11.SunPKCS11 \ -providerArg /path/to/hsm/hsm.conf Enter keystore password: user PIN
Enter the password of your HSM device. If you are using SoftHSM, enter your user PIN as the keystore password.
-
The
openidm-jwtsessionhmac-key
is used by the JWT session module to encrypt JWT session cookies. Generate the JWT session module key:keytool \ -genseckey \ -alias openidm-jwtsessionhmac-key \ -keyalg HmacSHA256 \ -keysize 256 \ -keystore NONE \ -storetype PKCS11 \ -providerClass sun.security.pkcs11.SunPKCS11 \ -providerArg /path/to/hsm/hsm.conf Enter keystore password: user PIN
-
The
openidm-localhost
certificate is used to support SSL/TLS. Generate the certificate:keytool \ -genkey \ -alias openidm-localhost \ -keyalg RSA \ -keysize 2048 \ -keystore NONE \ -storetype PKCS11 \ -providerClass sun.security.pkcs11.SunPKCS11 \ -providerArg /path/to/hsm/hsm.conf Enter keystore password: user PIN What is your first and last name? [Unknown]: localhost What is the name of your organizational unit? [Unknown]: What is the name of your organization? [Unknown]: OpenIDM Self-Signed Certificate What is the name of your City or Locality? [Unknown]: What is the name of your State or Province? [Unknown]: What is the two-letter country code for this unit? [Unknown]: Is CN=localhost, OU=Unknown, O=OpenIDM Self-Signed Certificate, L=Unknown, ST=Unknown, C=Unknown correct? [no]: yes
-
The
selfservice
certificate secures requests from the End User UI. Generate the certificate:keytool \ -genkey \ -alias selfservice \ -keyalg RSA \ -keysize 2048 \ -keystore NONE \ -storetype PKCS11 \ -providerClass sun.security.pkcs11.SunPKCS11 \ -providerArg /path/to/hsm/hsm.conf Enter keystore password: user PIN What is your first and last name? [Unknown]: localhost What is the name of your organizational unit? [Unknown]: What is the name of your organization? [Unknown]: OpenIDM Self Service Certificate What is the name of your City or Locality? [Unknown]: What is the name of your State or Province? [Unknown]: What is the two-letter country code for this unit? [Unknown]: Is CN=localhost,O=OpenIDM Self Service Certificate,OU=None,L=None,ST=None,C=None? [no]: yes
-
If you are not using the HSM provider for the truststore, you must add the certificates generated in the previous two steps to the default IDM truststore.
If you are using the HSM provider for the truststore, you can skip this step.
To add the
openidm-localhost
certificate to the IDM truststore, export the certificate from the HSM provider, then import it into the truststore:keytool \ -export \ -alias openidm-localhost \ -file exportedCert \ -keystore NONE \ -storetype PKCS11 \ -providerClass sun.security.pkcs11.SunPKCS11 \ -providerArg /path/to/hsm/hsm.conf Enter keystore password: user PIN Certificate stored in file exportedCert keytool \ -import \ -alias openidm-localhost \ -file exportedCert \ -keystore /path/to/openidm/security/truststore Enter keystore password: changeit Owner: CN=localhost, OU=Unknown, O=OpenIDM Self-Signed Certificate, L=… Issuer: CN=localhost, OU=Unknown, O=OpenIDM Self-Signed Certificate, L=… Serial number: 5d2554bd Valid from: Fri Aug 19 13:11:54 SAST 2016 until: Thu Nov 17 13:11:54 SAST 2016 Certificate fingerprints: MD5: F1:9B:72:7F:7B:79:58:29:75:85:82:EC:79:D8:F9:8D SHA1: F0:E6:51:75:AA:CB:14:3D:C5:E2:EB:E5:7C:87:C9:15:43:19:AF:36 SHA256: 27:A5:B7:0E:94:9A:32:48:0C:22:0F:BB:7E:3C:22:2A:64:B5:45:24:14:70:... Signature algorithm name: SHA256withRSA Version: 3 Extensions: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 7B 5A 26 53 61 44 C2 5A 76 E4 38 A8 52 6F F2 89 .Z&SaD.Zv.8.Ro.. 0010: 20 04 52 EE .R. ] ] Trust this certificate? [no]: yes Certificate was added to keystore
The default truststore password is changeit.
Configure IDM to support an HSM provider
To enable IDM to use an HSM provider, make the following configuration changes:
-
In your secret store configuration (
conf/secrets.json
), change themainKeyStore
andmainTrustStore
to reference the HSM. For example:{ "stores": [ { "name": "mainKeyStore", "class": "org.forgerock.openidm.secrets.config.HsmBasedStore", "config": { "storetype": "&{openidm.keystore.type|PKCS11}", "providerName": "&{openidm.keystore.provider|SunPKCS11-softHSM}", "storePassword": "&{openidm.keystore.password|changeit}", "mappings": [ { "secretId" : "idm.default", "types": [ "ENCRYPT", "DECRYPT" ], "aliases": [ "&{openidm.config.crypto.alias|openidm-sym-default}" ] }, { "secretId" : "idm.config.encryption", "types": [ "ENCRYPT", "DECRYPT" ], "aliases": [ "&{openidm.config.crypto.alias|openidm-sym-default}" ] }, { "secretId" : "idm.password.encryption", "types": [ "ENCRYPT", "DECRYPT" ], "aliases": [ "&{openidm.config.crypto.alias|openidm-sym-default}" ] }, { "secretId" : "idm.jwt.session.module.encryption", "types": [ "ENCRYPT", "DECRYPT" ], "aliases": [ "&{openidm.https.keystore.cert.alias|openidm-localhost}" ] }, { "secretId" : "idm.jwt.session.module.signing", "types": [ "SIGN", "VERIFY" ], "aliases": [ "&{openidm.config.crypto.jwtsession.hmackey.alias|openidm-jwtsessionhmac-key}" ] }, { "secretId" : "idm.selfservice.signing", "types": [ "SIGN", "VERIFY" ], "aliases": [ "selfservice" ] }, { "secretId" : "idm.selfservice.encryption", "types": [ "ENCRYPT", "DECRYPT" ], "aliases": [ "&{openidm.config.crypto.selfservice.sharedkey.alias|openidm-selfservice-key}" ] } ] } }, { "name": "mainTrustStore", "class": "org.forgerock.openidm.secrets.config.HsmBasedStore", "config": { "storetype": "&{openidm.keystore.type|PKCS11}", "providerName": "&{openidm.keystore.provider|SunPKCS11-softHSM}", "storePassword": "&{openidm.keystore.password|changeit}", "mappings": [ ] } } ], "populateDefaults": false }
The "populateDefaults": false
turns off the default key generation. This setting is required for an HSM key provider. -
In the IDM Java security file (
conf/java.security
), Specify the location of your PKCS #11 configuration file. For example:security.provider.14=SunPKCS11 /path/to/pkc11/config/pkcs11.conf
Templates for the
pkcs11.conf
file are included in your PKCS package.You should now be able to start IDM with the keys in the HSM provider.