The following integration guide details how to import keys into AWS CloudHSM for use with EJBCA.

Prerequisites

  1. EJBCA instance configured with AWS CloudHSM. For more information, refer to the AWS CloudHSM integration guide.
  2. AWS CloudHSM-client installed.
  3. OpenSSL
  4. Public and private keys to be imported to the CloudHSM.

Step 1 - Prepare the Keys

Private Key Requirements :

  1. Must follow RFC 5958 (obsoletes RFC 5208/PKCS#8).
  2. PEM Format (Base64-encoded DER).
  3. No password protection/encryption on the private key (a wrapping key will be used for this).

While existing keys may be in a range of formats (PFX/P12, JKS, PEM, etc.), the key_mgmt_util used in this guide expects a private key meeting the above requirements. To verify, check that the first line of the private key file starts with -----BEGIN PRIVATE KEY-----

Get the Public Key

Once the private key is confirmed to be in the right format, get the public key.

openssl rsa -in private.pem -out public.pem -pubout -outform PEM

Stage the keys on your EJBCA Instance

  1. Copy public and private keys that are to be imported, to the EJBCA instance (via SCP or other preferred method).

Step 2 - Generate a Wrapping Key for Secure Transport

  1. SSH into the EJBCA Instance and cd into the directory where the transferred keys reside.

  2. Run the Key Management Utility (key_mgmt_util): 

    /opt/cloudhsm/bin/key_mgmt_util

  3. Login as the crypto user:

    loginHSM -u CU -s cryptouser -hpswd

  4. Generate a wrapping key which will be used later to import the private key. 

    genSymKey -t 31 -s 32 -l aes256

  5. Note the Key Handle returned after generating the wrapping key.

Step 3 - Import the Public and Private Keys

  1. Import the public key

    importPubKey -f <FILE> -l <CKA_LABEL> -id <CKA_ID>

    Important

    Prefix the label with pub- and format the ID as the base name without a prefix or file extension. The ID is required to function in EJBCA. Example:

    importPubKey -f rsa001.pem -l pub-rsa001 -id rsa001

  2. Import the private key

    importPrivateKey -f <FILE> -l <CKA_LABEL> -id <CKA_ID> -w <WrappingKeyHandle>

    Important

    Prefix the label with priv- and format the ID as the base name without a prefix or file extension. The ID is required to function in EJBCA. Example:

    importPrivateKey -f rsa001.key -l priv-rsa001 -id rsa001 -w 4

  3. Verify keys are imported:

    findkey

  4. Confirm the number of keys present corresponds to the number imported/generated. In this example, it should be three. (Public key, private key, wrapping key)

  5. Exit the key_mgmt_util by typing exit

Next Steps

Once the public and private keys are successfully imported to the CloudHSM, the next step is to create a CryptoToken in EJBCA.

With this step complete, the imported keys in the slot should populate and be available for use.

Troubleshooting

  1. If keys are not appearing in EJBCA after generating a crypto token, SSH into the EJBCA instance, switch to the wildfly user and run the following command to confirm all expected keys are present and each relevant key has both a CKA_ID and CKA_LABEL associated to it.

    /opt/ejbca/dist/p11ng-cli/p11ng-cli.sh listobjects --lib-file /opt/cloudhsm/lib/libcloudhsm_pkcs11.so --slot-ref SLOT_LABEL --slot cavium

    Sample output showing missing CKA_ID for the Private Key

    [ec2-user@ip-172-31-47-62 importKeys]$ sudo su wildfly
    bash-4.2$ /opt/ejbca/dist/p11ng-cli/p11ng-cli.sh listobjects --lib-file /opt/cloudhsm/lib/libcloudhsm_pkcs11.so --slot-ref SLOT_LABEL --slot cavium
    Enter slot login password:


    Private Key Objects: [10]

    Object 10
       CKA_ID:    -
       CKA_LABEL:    0x707269762d7369676e4b65795445535445585043413031 "priv-rsa001"


    Public Key Objects: [8]

    Object 8
       CKA_ID:    0x7369676e4b65795445535445585043413031 "rsa001"
       CKA_LABEL:    0x7075622d7369676e4b65795445535445585043413031 "pub-rsa001"