Previous: Up: Deploymenet OptionsEnd of book

Enhanced Private Key Security

Although version 4.0 of Bare Metal added additional protection of private keys, it only protected keys at rest. When keys were "activated," they were loaded into the agent's process memory completely unencrypted. Some deployments may lock down access to the agent tight enough that this may be acceptable, but it still leaves the keys venerable to any entity with access to the agent's process memory.

With governmental and other high security agencies now implementing Direct, a higher level of key protection is required not only by the agencies themselves, but by the systems that they rely upon (i.e. your system). A common approach to the private key protection problem is to utilized PKCS11 token such as NIST certified hardware security modules where the keys are only activated (i.e. utilized for cryptographic operations in their unecrypted form) inside the tokens. Beginning with version 5.0 of Bare Metal, PKCS11 tokens are supported using this model.

NOTE The following is an optional configuration; Bare Metal will still operate in the same manner as version 4.0 if the following configuration options are not implemented. If enhanced key security is implemented, any keys installed before implementation will continue to operate and function as they did in previous versions (they system is backward compatible). If you wish to use enhance key security on previously installed keys, you will need to remove them an reimport them.

Key At Rest Protection

Version 4.0 of Bare Metal first implemented key protection by encrypting p12 containers in the configuration service. The configuration service was configured with a secret key that could either be bootstrapped in the Spring configuration or loaded from a PKCS11 token. The private key was only encrypted when at rest and was decrypted as soon as it was read from the configurations store's database. This meant that the private key was accessible at any time it was outside of the configuration service including when they private key was first loaded into the system.

To ensure that private keys always stay encrypted until they are needed for cryptographic operations, PKCS11 tokens utilize key "wrapping" and "unwrapping". Wrapping encrypts a private key utilizing a symmetric secret key that is also stored and only activated in the PKCS11 module (it doesn't help to secure private keys at rest if their key encryption key is exposed). Unwrapping decrypts the private key using the same symmetric secret key, however the unwrapping operation results in the private being loaded into and only decrypted inside the PKCS11 token. That application using the private key is only give a logical handle to the secret key and can't get access to the sensitive key material.

Utilizing the wrapping and unwrapping model, the configuration service is no longer responsible for encrypting and decrypting p12 files. Instead, certificates and their private keys are loaded into and retrieved from the configuration service in their wrapped form. The config-ui is now responsible for wrapping the private keys as they loaded into the application and the agent is responsible unwrapping keys at the time they are needed for cryptographic operations.

PKCS11 Token Selection

There are many PKCS11 options available on the market, however it is recommended to utilize a module that is NIST certified. Additionally it MUST have support for the Java PKCS11 model and optimally support (but not required) wrapping private key with an AES128 secret key. Value adds to look for are good documentation, key management tooling, random number generation, and access from multiple nodes for high availability and scalability.

Key Encryption Key

The first step is to create the symmetric key that will encrypt the private keys; this is also known as the key encryption key. The key encryption key is an AES128 key, and its generation is dependent on the tooling at hand. Some PKCS11 modules come with tools that enable creation of AES128 keys on the module; see your token documentation for details. If your token does not have a tool, Bare Metal ships with the PKCS11SecretKeyManager tool to create random AES128 keys. In either case, the key encryption key is assigned a name (or alias) that will be used by the agent (and optionally the config-ui) to reference to the key encryption key.


The PKCS11SecretKeyManager accesses a PKCS11 token for the purpose of managing secret keys on the token. Before you can use the tool, you will need to check the documentation of your token to understand how it works with the Java PKCS11 model. There are two generally ways:

  • The token utilizes the Sun PKCS11 JCE provider and is configured using a file that adheres to the Sun PKCS11 configuration guide. Most notably, this file contains the name of the native library that implements the token's bridge interface.
  • The token ships its own PKCS11 JCE provider library. In this case, the configuration is completely dependent on the token vendor's implementation. In many cases, a file or input stream is passed to the KeyStore load method that contains configuration information.

The PKCS11SecretKeyManager supports both methods.

Some tokens may partially support the PKCS11 interface, but may require proprietary code to perform some operations. For example, the Gemalto (formerly SafeNet) ProtecteServer HSM supports almost all of the functionality required by the Direct reference implementation through its PKCS11 interface, however, it does not support key wrapping without using a proprietary API. The reference implementation has attempted to fill these gabs on a case by case bases through the use of the direct-jce-providers.jar module. This module provides a wrapper/shim around the token's JCE implementation and fills in the missing functionality to make the PKCS11 implentation complete for the purposes of Direct.

The PKCS11SecretKeyManager has a couple of command line arguments:

  • -keyStoreCfg: This parameter is always required and is the path to a file that contains the following information:
    • JCE provider class name. This is will be for token that utilize the Sun JCE provider. Tokens that implement their own providers should indicate the provider class name in their documentation.
    • Key Store Type: This is the type of key store. If not present, this defaults to PKCS11. Some tokens will require a proprietary name; see the tokens documentation for details.
    • Key Store Source: For tokens that implement their own JCE providers, this is a string that is passed to the KeyStore load method.
  • -pkcscfg: For tokens that utilized JCE provider, this is a required parameter that is the path to a file that contains the Sun PKCS11 compliant configuration information.

The following is an example of the contents of the keyStoreCfg file for a token that uses the JCE provider:

The following is an example of the contents of the keyStoreCfg file for a token that uses its own JCE provider:


The following is an example of the contents of the required pkcscfg for a token that uses the JCE provider:


Once you have to proper configuration completed, you need to make sure you have all native libraries and jar files in the proper location. Most likely, the native libraries will be installed when you run the installation software package that came with your token. For tokens that utilize the JCE provider, you need to find the location of the native library the implements the Java PKCS11 bridge. For tokens that implement their own JCE providers, they will most likely have a combination of native libraries and a jar file. You will need to add the jar file to the Bare Metal /tools/lib directory.

The following is an example command to launch the tool for a token that uses the JCE provider:

	./ -keyStoreCfg keyStore.cfg -pkcscfg pkcs11.cfg

The following is an example command to launch the tool for a token that uses its own JCE provider. Note it does not need a pkcscfg file:

	./ -keyStoreCfg keyStore.cfg

Once you launch the tool and entered the correct pin/password, creating random secret key is done by executing the following command. In most cases, using this command will utilize a random number generator implemented on the token. NOTE You can use any key name you want, but it MUST match the key alias name in the config-ui and gateway (agent) configuration files.

	CreateRandomSecretKey privateKeyWrapperSecret

Config UI Configuration

When importing unencrypted keys with enhanced key protection, the config-ui can wrap unencrypted keys before sending them to the configuration service. NOTE This is not the preferred method when using key wrapping. A more appropriate approach is to generate the keys on the HSM, export/wrap the keys using the PKCS11SecretKeyManager tool, and import the wrapped key into the configuration service using the config-ui (or the ConfigManage command line) tool. If you export/wrap the keys using the PKCS11SecretKeyManager tool, the configuration in the below paragraphs is not necessary.

In order to do this, the config-ui web application will need access to the PKCS11 token. The token is configured similarly to the way it is configured in the PKCS11SecretKeyManager tool. To configure the token, you will need to uncomment the PKCS11 bean configuration section at the bottom of the <DIRECTHOME>/apache-tomcat-xxx/webappsconfig-ui/WEB-INF/config-servlet.xml file. Once this configuration section is uncommented, you will set the parameters for the token in the <DIRECTHOME>/apache-tomcat-xxx/webappsconfig-ui/WEB-INF/classes/properties/ file. The file contains the following properties for the token:

Propert NameProperty Description
config-ui.keyprotection.pkcs11.pinThe pin/password to authenticate to the token
config-ui.keyprotection.pkcs11.keyStoreTypeThe Key Store Type. This is generally set to PKCS11 for tokens that utilize the Sun PKCS11 JCE provider.
config-ui.keyprotection.pkcs11.keyStoreSourceA string that is passed to the KeyStore load method. This is generally used for tokens that implement their own JCE providers
config-ui.keyprotection.pkcs11.keyStoreProviderNameThe PCKS11 JCE provider class
config-ui.keyprotection.pkcs11.pcks11ConfigFileFor tokens that use the Sun PKCS11 JCE provider, that path of the file that contains the Sun PKCS11 compliant configuration
config-ui.keyprotection.pkcs11.privateKeyPassPhraseAliasThe alias of the key encryption key. This MUST match the name of the key created in the PKCS11SecretKeyManager tool (or tool provider by the token vendor).

Similar to the PKCS11SecretKeyManager tool, you will need to make sure all native libaries are properly installed. If the token implements its own JCE provider, you need to copy the vendor's jar file to the <DIRECTHOME>/apache-tomcat-xxx/webappsconfig-ui/WEB-INF/lib directory.

Gateway and Agent Configuration

To properly unwrap the keys and utilize the token, the gateway (and subsequently the agent) needs to also be configured. Depending on the version of James, you will need to edit the following files:

The configuration options are found under the configuration NHINDSecurityAndTrustMailet mailet, and contains two commented out templates: one for a token that utilizes the Sun PKCS11 JCE provider and one a token the uses its own provider. The configuration paremeter names are very simliar to the ones decribed in the last two sections, and are fully documented in the gateway PKCS11 deployment documentation. You will again need to ensure that the appropriate token native libraries are installed and any jar files copied to the following locations:

NOTE If you are using James 2, pay close attention to the documentation preceding the configuration templates in the config.xml file about the necessity to copy the Sun Jars.

Example Workflow for Creating and Importing Certificates and Keys

The preferred methodology for creating and importing keys is to generate the public/private key pair on the HSM and import the wrapped private key along with its certificate into the configuration service using the config-ui of the ConfigManager command line tool. To go from creating a public/private key pair to utlimately having a signed certificate from a CA takes a few steps; these steps are outline below and utilized the PKCS11SecretKeyManager tool. These steps assume that have properly configuration the PKCS11SecretKeyManager tool to communicate with your HSM using the steps PKCS11SecretKeyManager section of this document.

Secret Key Creation All enhanced key protection is done with an AES128 secret key. To create a secret key, you can use the CREATERANDOMSECRETKEY or CREATEUSERSECRETKEY commands. Using the CREATERANDOMSECRETKEY utilized the random number generation functionality (if available) of your HSM to create a new random secret key; this is the preferred method. The example below creates a secret key using a key name that matches the default configuration in the gateway (agent) and the default optional configuration of the config-ui.


To verify that the secret key was created, issue the following command:


Key Pair Creation

The first step to creating any certificate for use with Direct is to create a public/private key pair. Once you have launched the PKCS11SecretKeyManager tool, you create a key pair by using the CREATEKEYPAIR command. With this command, you give the key pair name with optional key size (defaults to 2048). The key pair name will be used in subsequent commands to generate a CSR and to export/wrap the privateKey. The example command below creates a key pair named "directSecEmailDigSig" with a key length of 2048 bytes. NOTE If you are creating certificates with single use keys, you need to create a key pair for the encryption certificate and a key pair for the digital signature certificate.

	CREATEKEYPAIR directSecEmailDigSig	

To verify that the key pair was created, issue the following command (this will show both RSA key pairs and secret keys):


CSR Creation and CSR Signing

Now that you have key pair, you can generate a certificate signing request (CSR) that you can be uploaded to a 3rd party CA other other CA signing tool for creation of a certificate. To generate a CSR, use the CREATECSR command to specify the attributes that you want in the certificate. The sample command below creates a CSR for a single key use encryption certificate using the directSecEmailDigSig key pair generated in the previous section for a domain level certificate named NOTE If you are creating certificates with single use keys, you will create two CSRs using the exacts same attributes with the exception that key usage and key pair parameters will be different.

	CREATECSR directSecEmailDigSig KeyEncipherment C=US S=Missouri "L=Kansas City" "O=Direct RI"

Once you execute this command, the tool will create a PEM encoded CSR file that you can submit to you CA for signing. For testing purposes, the reference implementation's certGen tool can now sign CSR files to generate a certificate.

Export/Wrap the Private Key

The next step is to export the private key from the system. This step will utilize the AES128 secret to encrypt the private key and export the encrypted private key to a file. The following example command wraps the private key associate with directSecEmailDigSig key pair using the privateKeyWrapperSecret secret key. You can optionally provide a name for the wrapped key file, but the system will auto generate one if you don't provide a file name.

	EXPORTPRIVATEKEY directSecEmailDigSig privateKeyWrapperSecret

Once you execute this command, the tool will create a file containing the wrapped private key. You will import this wrapped key file along with the singed certificate from the previous section into the configuration service utilizing either the config-ui or the ConfigManager command line tool.

Importing the Wrapped Key and Certificate

Now that you have a wrapped key and singed certificate, it's time to import the key and certificate into the system for use by the security and trust agent and Direct message exchange. You have two ways to import the files. If you are using the config-ui, starting with version 5.1 of the stock assembly, you can import the wrapped key and certificate files into the system using the config-ui's certificate tab. If you prefer to use the ConfigManager command line tool, then you can import the wrapped private key file and certificate file into the system using the ADDPRIVATECERTWITHWRAPPEDKEY command. The example command below imports a certificate file and wrapped key into the system.

	ADDPRIVATECERTWITHWRAPPEDKEY directSecureHealthEmail_encCert.der directSecEmailDigSig-privKey.der

The certificate and private key are ready to be used by your Direct implementation.

Clean Up

Once you have imported the private key and certificate into your system, it's most likely not be necessary for the key pair to remain in the HSM (unless you need it later for reissuing certificates with the same key pair). Most HSMs have limit storage, so it's a good idea to clean up your key pair once your done. To remove a key pair from the HSM, use the REMOVEKEY command. The example command below deletes the key pair generated earlier in the section from the HSM.

	REMOVEKEY directSecEmailDigSig

Previous: Up: Deploymenet OptionsEnd of book