How do I use OpenSSL and the key_mgmt_util command line tool to securely transfer my keys to CloudHSM?

8 minute read
2

I want to use the unWrapKey command with the key_mgmt_util command line tool to import local keys to AWS CloudHSM.

Resolution

Encrypt your payload key with an ephemeral AES key. Encrypt the ephemeral AES with your public key from a key pair. Then, join the encrypted payload key and encrypted ephemeral key into a single file. The file is sent to your CloudHSM in an encrypted format, and the private key decrypts the file from the key pair. The AES_KEY_WRAP mechanism decrypts the ephemeral AES key and uses the key to decrypt your payload key.

Create the following keys:

  • Payload AES or RSA key. This is the key that you import and use with your CloudHSM.
  • Temporary AES key required by AES_KEY_WRAP to encrypt the payload. It's a best practice to use AES because there are no size limits on what can be encrypted.
  • RSA key pair that's used to securely wrap and unwrap the keys into your CloudHSM.

Before you begin, make sure that you have a patched version of OpenSSL to allow envelope wrap. For instructions, see How can I patch OpenSSL to activate use with the CloudHSM CKM_RSA_AES_KEY_WRAP mechanism?

Create, encrypt, and import the local keys

To create, encrypt, and import the local keys, complete the following steps:

  1. Run the following commands to create the payload, ephemeral, and RSA keys:
    Tip: To track your files, create these keys in their own directory.

    openssl rand -out payload_aes 32openssl rand -out ephemeral_aes 32
    openssl genrsa -out private.pem 2048
    openssl rsa -in private.pem -out public.pem -pubout -outform PEM
    
  2. Run the following command to output the raw hex values of the ephemeral AES key into a variable:

    EPHEMERAL_AES_HEX=$(hexdump -v -e '/1 "%02X"' < ephemeral_aes)
    

    Note: Make sure that you have the hexdump utility installed. If you don't install hexdump, then the preceding command returns an error. Refer to your operating system (OS) documentation for instructions on how to install the hexdump utility.

  3. Run the OpenSSL enc command to wrap the payload with the ephemeral AES key:

    OPENSSL_V111 enc -id-aes256-wrap-pad -K $EPHEMERAL_AES_HEX -iv A65959A6 -in payload_aes -out payload_wrapped
    

    Note: The -id-aes256-wrap-pad cipher is the RFC 3394-compliant wrap mechanism that coincides with CKM_RSA_AES_KEY_WRAP. The RFC 3394 extension, RFC 5649, sets the -iv values. For more information see, Advanced Encryption Standard (AES) key wrap with padding algorithm and Advanced Encryption Standard (AES) key wrap algorithm on the Datatracker website.

  4. Encrypt the AES key with the public key from the RSA key pair:

    OPENSSL_V111 pkeyutl -encrypt -in ephemeral_aes -out ephemeral_wrapped -pubin -inkey public.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha1 -pkeyopt rsa_mgf1_md:sha1
    
  5. From the local machine, join the encrypted payload key and ephemeral AES key into a single file that's named rsa_aes_wrapped:

    cat ephemeral_wrapped payload_wrapped > rsa_aes_wrapped
    

    Note: If you used exportPubKey to create the RSA key pair on the HSM and exported the public key, then proceed to step 10.

  6. Import the RSA private key into the CloudHSM from your local machine. To manage the import, use the importPrivateKey to create a persistent AES key in the HSM. Replace user-name and user-password with your CloudHSM username and password:

    /opt/cloudhsm/bin/key_mgmt_util singlecmd loginHSM -u CU -s user-name -p user-password  genSymKey -t 31 -s 32 -l aes256
    

    Warning: The preceding command can locally record details of your username and password. After you transfer your keys, it's a best practice to change your password. Don't specify the crypto-user password. Instead, write a shell script so that the password isn't recorded in the shell history. The shell script receives all the arguments for key_mgmt_util and sends them to this command.

  7. Note the AES key handle that's used to import the private RSA key. In the following example output, the key handle is 7:

    Command: genSymKey  -t  31  -s  32  -l  aes256        Cfm3GenerateSymmetricKey returned: 0x00 : HSM Return: SUCCESS
            Symmetric Key Created.  Key Handle: 7
            Cluster Error Status
            Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
    
  8. Import the private key, and then wrap it into the HSM. The import is secured with the persistent AES key. Replace -w 7 with your key handle:

    /opt/cloudhsm/bin/key_mgmt_util singlecmd singlecmd loginHSM -u CU -s user-name -p user-password  importPrivateKey -l private -f private.pem -w 7
    
  9. Note the imported RSA private key handle. In the following example output, the imported RSA private key is 8:

    Cfm3WrapHostKey returned: 0x00 : HSM Return: SUCCESS        Cfm3CreateUnwrapTemplate2 returned: 0x00 : HSM Return: SUCCESS
            Cfm3UnWrapKey returned: 0x00 : HSM Return: SUCCESS
            Private Key Imported.  Key Handle: 8
            Cluster Error Status
            Node id 0 and err state 0x00000000 : HSM Return: SUCCESS
    
  10. Run the following command to use the imported RSA private key with the unWrapKey to unwrap the joined payload key into the HSM. Replace -w 8 with your private key handle:

    /opt/cloudhsm/bin/key_mgmt_util singlecmd -u CU -s user-name -p user-password  unWrapKey -f rsa_aes_wrapped -w 8 -m 7 -noheader -l secretkey -kc 4 -kt 31
    

    Note: you must use -kc 4 -kt 31 to unwrap AES keys and -kc 3 -kt 0 to unwrap RSA private keys. For more information about how to use the -m, -kc and -kt parameters, see the unWrapKey example.

You receive a successful import of the payload AES key that's similar to the following output:

Cfm3CreateUnwrapTemplate2 returned: 0x00 : HSM Return: SUCCESS        Cfm2UnWrapWithTemplate3 returned: 0x00 : HSM Return: SUCCESS
        Key Unwrapped.  Key Handle: 10
        Cluster Error Status
        Node id 0 and err state 0x00000000 : HSM Return: SUCCESS

Note: In the preceding example, you can use key handle 10 of the new unwrapped key in the CloudHSM.

Verify that you imported the payload AES key

To verify that you imported the payload AES key, complete the following steps:

  1. Use the wrap key -w 7 to export the payload AES key back to disk. Replace payload key handle 10 with your imported payload AES key value:

    /opt/cloudhsm/bin/key_mgmt_util singlecmd loginHSM -u CU -s user-name -p user-password exSymKey -k 10 -w 7 -out HSM.key
    
  2. Run the following command to compare the imported payload key with the payload_aes key:

    diff HSM.key payload_aes --report-identical-files
    

If the HSM.key and payload_aes keys are identical, then you receive the following output:

Files HSM.key and payload_aes are identical

Import the RSA payload

To import the payload, complete the following steps:

  1. To unwrap an RSA private key into the HSM, run the following commands to change the payload key to an RSA private key:

    openssl genrsa -out payload_rsa.pem 2048openssl rand -out ephemeral_aes 32
    openssl genrsa -out private.pem 2048
    openssl rsa -in private.pem -out public.pem -pubout -outform PEM
    
  2. Use a plain text editor to check the format of the RSA keys:

    PKCS1 format: -----BEGIN RSA PRIVATE KEY----- - PKCS8 format: -----BEGIN PRIVATE KEY-----

    Note: The RSA keys are in PKCS #1 format. However, the key_mgmt_util tool assumes that the private key is in PKCS #8 DER format.

  3. To convert the payload_rsa.pem key into pkcs8 format and DER encoded, run the following command:

    openssl pkcs8 -topk8 -inform PEM -outform DER -in payload_rsa.pem -out payload_rsa_pkcs8.der -nocrypt
    
  4. Complete steps 2-9 from the Create, encrypt, and import the local keys section. Replace payload_aes with payload_rsa_pkcs8.der.

  5. Run the following command to unwrap the payload RSA private key into the CloudHSM, and then note the output key handle:

    /opt/cloudhsm/bin/key_mgmt_util singlecmd loginHSM -u CU -s user-name -p user-password unWrapKey -f rsa_aes_wrapped -kc 3 -kt 0 -w 8 -l private_key -m 7 -noheader
    

    Note: you must use -kc 4 -kt 31 to unwrap AES keys and -kc 3 -kt 0 to unwrap RSA private keys.

You now have the payload RSA key that's unwrapped into the HSM.

Verify that you imported the payload RSA private key

To verify that you imported the payload RSA private key, complete the following steps:

  1. Use the key wrap to export the payload RSA private key back to disk. Replace payload key handle 25 with your payload RSA private key value:

    /opt/cloudhsm/bin/key_mgmt_util singlecmd loginHSM -u CU -s user-name -p user-password exportPrivateKey -k 25 -w 7 -out HSM_rsa_private.key
    
  2. Run the following command to convert your payload_rsa key into PKCS #8 format:

    openssl pkcs8 -topk8 -inform PEM -outform PEM -in payload_rsa.pem -out payload_rsa_pkcs8.pem -nocrypt
    
  3. Run the following command to compare the imported payload key with the payload_rsa key:

    diff HSM_rsa_private.key payload_rsa_pkcs8.pem --report-identical-files
    

If the HSM_rsa_private.key and payload_rsa_pkcs8.pem keys are identical, then you receive the following output:

Files HSM_rsa_private.key and payload_rsa_pkcs8.pem are identical

Related information

Supported mechanisms

AWS OFFICIAL
AWS OFFICIALUpdated 4 months ago