I created a customer master key (CMK) in AWS Key Management Service (AWS KMS), specified the Key Material Origin as External, chose RSAES_OAEP_SHA_256 as the algorithm for the wrapping key, and used OpenSSL to encrypt my key material with the wrapping key. However, when I import my encrypted key material, the request fails and I get an error message regarding “InvalidCiphertext”. How can I avoid this import error? 

By default, OpenSSL uses the SHA-1 hash function. To avoid import errors when you use the RSAES_OAEP_SHA_256 algorithm (SHA-256 hash function), encrypt your key material with OpenSSL using the openssl pkeyutl command and specify the parameters –pkeyopt rsa_padding_mode:oaep and –pkeyopt rsa_oaep_md:sha256.

The full procedure to import key material into AWS KMS using OpenSSL and RSAES_OAEP_SHA_256 is as follows:

1.    Create a CMK using External for the key material origin.

2.    Download the wrapping (public) key and the import token.

3.    Generate a 256-bit symmetric key.

4.    Verify that your OpenSSL version supports openssl pkeyutl.

5.    Encrypt your key material with the wrapping key.

6.    Import your encrypted key material.

Note: If you’re using the RSAES_OAEP_SHA_1 encryption algorithm for your wrapping key, see How To Import Key Material.

Create a CMK using External for the key material origin

Run the following AWS Command Line Interface (AWS CLI) commands to create a CMK for external key material.

Note: Make sure to replace the export REGION and export KEY_ALIAS values with the details for your key.

export REGION=us-east-1
export KEY_ALIAS=cmk_with_externalmaterial
aws kms --region $REGION create-key --origin EXTERNAL --description $KEY_ALIAS
export KEY_ID=`aws kms --region $REGION list-keys --query 'Keys[?Description == "$KEY_ALIAS"].KeyId' --output text`
aws kms --region $REGION create-alias --alias-name alias/$KEY_ALIAS --target-key-id $KEY_ID

Your newly created CMK will be in the Pending Import status until you import the key material. Run the following command to view the key’s status.

aws kms --region $REGION describe-key --key-id $KEY_ID

Download the wrapping (public) key and the import token

Run the following AWS CLI commands to get the PublicKey (wrapping key) and ImportToken values, decode both values using Base64, and store them into separate files. Note that the RSAES_OAEP_SHA_256 wrapping algorithm is specified in the get-parameters-for-import command.

export KEY_PARAMETERS=`aws kms --region $REGION get-parameters-for-import --key-id $KEY_ID --wrapping-algorithm RSAES_OAEP_SHA_256 --wrapping-key-spec RSA_2048`
echo $KEY_PARAMETERS | sed -e 's/[{}]/''/g' | awk '{n=split($0,a,","); for (i=1; i<=n;
i++) print a[i]}' | sed 's/^[ ]*//' | grep -i publickey | cut -d " " -f 2 | cut -c 2- | rev | cut -c 2- | rev > PublicKey.b64
echo $KEY_PARAMETERS | sed -e 's/[{}]/''/g' | awk '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/^[
]*//' | grep -i importtoken | cut -d " " -f 2 | cut -c 2- | rev | cut -c 2- | rev > ImportToken.b64
openssl enc -d -base64 -A -in PublicKey.b64 -out PublicKey.bin
openssl enc -d -base64 -A -in ImportToken.b64 -out ImportToken.bin
rm *.b64

These commands store the wrapping key in PublicKey.bin and the import token in ImportToken.bin.

Generate a 256-bit symmetric key

The key material must be a 256-bit (32-byte) symmetric key. Run one of the following commands to generate the key.

OpenSSL

openssl rand -out PlaintextKeyMaterial.bin 32

dd

dd if=/dev/urandom of=PlaintextKeyMaterial.bin bs=32 count=1

Verify that your OpenSSL version supports openssl pkeyutl

To encrypt your key material with RSAES_OAEP_SHA_256 as the wrapping algorithm, use the openssl pkeyutl command. This command is available only on OpenSSL 1.0.2 and later versions.
If you’re using a RHEL-based Linux computer, such as an EC2 instance launched with an Amazon Linux AMI, then follow these steps.

1.    Run the following command to check your OpenSSL version.

openssl version

2.    If you need to update OpenSSL, then run the following command.

sudo yum –y update openssl

If you’re using macOS, then follow these steps.

1.    Run the following Homebrew commands.

brew update
brew upgrade openssl
brew info openssl

2.    The last command shows you that OpenSSL is installed in /usr/local/opt/openssl/bin/. Confirm the OpenSSL version by running this command.

/usr/local/opt/openssl/bin/openssl version

3.    To always use the most recent OpenSSL version, edit ~/.bash_profile and add the following line at the end of the file:

export PATH="/usr/local/opt/openssl/bin:$PATH"

4.    After adding the line, run the following command.

source ~/.bash_profile

5.    To verify the change in your macOS environment, run the following command.

echo $PATH
openssl version

Encrypt your key material with the wrapping key

Run the following command to encrypt your key material using the most recent version of OpenSSL and the wrapping key you previously downloaded.

Note: The wrapping key is stored in PublicKey.bin.

openssl pkeyutl -in PlaintextKeyMaterial.bin -out EncryptedKeyMaterial.bin -inkey PublicKey.bin -keyform DER -pubin -encrypt -pkeyopt rsa_padding_mode:oaep
-pkeyopt rsa_oaep_md:sha256

The command generates EncryptedKeyMaterial.bin, which you’ll use as the encrypted key material to import into the CMK.

Import your encrypted key material

Run the following AWS CLI command to import the encrypted key material into the CMK.

aws kms --region $REGION import-key-material --key-id $KEY_ID --encrypted-key-material fileb://EncryptedKeyMaterial.bin --import-token fileb://ImportToken.bin --expiration-model KEY_MATERIAL_DOES_NOT_EXPIRE

After the import is complete, the key’s status changes to Enabled. Run the following command to verify the key’s status.

aws kms --region $REGION describe-key --key-id $KEY_ID

Did this page help you? Yes | No

Back to the AWS Support Knowledge Center

Need help? Visit the AWS Support Center

Published: 2017-11-15