How can I securely transfer my keys to CloudHSM with OpenSSL and the key_mgmt_util command line tool?
I have local keys that I want to import to AWS CloudHSM using the unWrapKey command with the key_mgmt_util command line tool. However, I can't import or wrap plaintext keys.
Resolution
Encrypt your payload key with an ephemeral AES key. Encrypt the ephemeral AES with your public key from a key pair. Then, concatenate the encrypted payload key and encrypted ephemeral key into a single file. The concatenated file is sent to your CloudHSM in its encrypted format, and then decrypted by the private key 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 used to securely wrap and unwrap these keys into your CloudHSM.
Before you begin, make sure that you have a patched version of OpenSSL to allow envelope wrapping. 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
1. Run these commands to create the payload, ephemeral, and RSA keys.
Tip: Create these keys in their own directory to track your files.
openssl rand -out payload_aes 32 openssl rand -out ephemeral_aes 32 openssl genrsa -out private.pem 2048 openssl rsa -in private.pem -out public.pem -pubout -outform PEM
2. Output the raw hex values of the ephemeral AES key into a variable with this command.
EPHEMERAL_AES_HEX=$(hexdump -v -e '/1 "%02X"' < ephemeral_aes)
Note: Make sure that you have the hexdump utility installed, or this command returns an error. Refer to your OS documentation on how to install the hexdump utility.
3. Use the OpenSSL enc command to wrap the payload with the ephemeral AES key. The -id-aes256-wrap-pad cipher is the RFC 3394 compliant wrapping mechanism that coincides with CKM_RSA_AES_KEY_WRAP. The -iv values are set by RFC 5649 (an extension to RFC 3394).
OPENSSL_V111 enc -id-aes256-wrap-pad -K $EPHEMERAL_AES_HEX -iv A65959A6 -in payload_aes -out payload_wrapped
4. Encrypt the AES key with the public key from the RSA key pair that you created in step 1.
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, concatenate the encrypted payload key and ephemeral AES key into a single file named rsa_aes_wrapped.
cat ephemeral_wrapped payload_wrapped > rsa_aes_wrapped
6. Import the RSA private key into the CloudHSM from your local machine. Create a persistent AES key in the HSM to manage the import using importPrivateKey.
Note: Replace user-name and user-password with your CloudHSM user name and password.
Note: If you created the RSA key pair on the HSM and exported the public key using exportPubKey, then you can skip steps 6-9.
/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password genSymKey -t 31 -s 32 -l aes256
Warning: The command can record details of your user name and password locally. After transferring your keys, it’s a best practice to change your password. Instead of specifying the crypto-user password, you can also write a shell script to avoid having the password recorded in the shell history. This shell script will receive all the arguments for key_mgmt_util, and send them to this command. This allows you to use the shell script to run the command above as well as the other key_mgmt_util commands below.
7. You receive an output similar to the following. Note the AES key handle—it's used to import the private RSA key. In this example, 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 wrap it into the HSM. The import is secured with the persistent AES key you created in step 6. Note: Replace option -w 7 with your key handle.
/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password importPrivateKey -l private -f private.pem -w 7
9. You receive an output similar to the following. Note the imported RSA private key handle. In this example, 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. Unwrap the concatenated payload key into the HSM using the imported RSA private key with the unWrapKey command. This example uses -w 8 as the key handle of the imported RSA private key.
Note: Replace -w 8 with your private key handle.
/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -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 on using the -m, -kc and -kt parameters, see the unWrapKey example.
11. You receive a successful import of the payload AES key similar to the following output:
Note: In this example, key handle 10 of the new unwrapped key can be used in the CloudHSM.
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
Verify that you imported the payload AES key
1. Export the payload AES Key back to disk using the wrapping key -w 7. Replace payload key handle 10 with your own value of your imported payload AES key.
/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password exSymKey -k 10 -w 7 -out HSM.key
2. Run this command to compare the imported payload key with the payload_aes key.
diff HSM.key payload_aes --report-identical-files
3. If the HSM.key and payload_aes keys are identical, you receive the following output:
Files HSM.key and payload_aes are identical
Import the RSA payload
1. If you want to unwrap an RSA private key into the HSM, run these commands to change the payload key to an RSA private key.
openssl genrsa -out payload_rsa.pem 2048 openssl rand -out ephemeral_aes 32 openssl genrsa -out private.pem 2048 openssl rsa -in private.pem -out public.pem -pubout -outform PEM
2. RSA Keys created in step 1 from the Steps required for Import RSA payload section using OpenSSL are in PKCS #1 format. However, the key_mgmt_util tool assumes that the private key is in PKCS #8 DER format. View the keys in plaintext using your favorite text editor to confirm the format similar to the following:
- PKCS1 format: -----BEGIN RSA PRIVATE KEY----- - PKCS8 format: -----BEGIN PRIVATE KEY-----
3. To convert the payload_rsa.pem key into pkcs8 format and DER encoded, run this command:
openssl pkcs8 -topk8 -inform PEM -outform DER -in payload_rsa.pem -out payload_rsa_pkcs8.der -nocrypt
4. Follow steps 2-9 from the Create, encrypt, and import the local keys section.
Note: replace payload_aes with payload_rsa_pkcs8.der.
5. Run this command to unwrap the payload RSA private key into the CloudHSM, and 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 unwrapped into the HSM.
Verify that you imported the payload RSA private key
1. Export the payload RSA private key back to disk using the wrapping key you created earlier. Replace payload key handle 25 with your own value of your imported payload RSA private key.
/opt/cloudhsm/bin/key_mgmt_util Cfm3Util singlecmd loginHSM -u CU -s user-name -p user-password exportPrivateKey -k 25 -w 7 -out HSM_rsa_private.key
2. Run this command to convert your payload_rsa key into PKCS #8 format without converting to DER.
openssl pkcs8 -topk8 -inform PEM -outform PEM -in payload_rsa.pem -out payload_rsa_pkcs8.pem -nocrypt
3. Run this command to compare the imported payload key with the payload_rsa key.
diff HSM_rsa_private.key payload_rsa_pkcs8.pem --report-identical-files
4. If the HSM_rsa_private.key and payload_rsa_pkcs8.pem keys are identical, you receive the following output:
Files HSM_rsa_private.key and payload_rsa_pkcs8.pem are identical
Related information

Contenido relevante
- ¿Cómo puedo enumerar las concesiones de claves y entidades principales de KMS por región en AWS KMS?OFICIAL DE AWSActualizada hace 2 años
- OFICIAL DE AWSActualizada hace 10 meses
- OFICIAL DE AWSActualizada hace 6 meses
- OFICIAL DE AWSActualizada hace 10 meses