I'm using OpenSSL to import my key into AWS KMS, but I'm getting an "InvalidCiphertext" error. How can I fix this?

5 minute read
0

I created an AWS KMS key in AWS Key Management Service (AWS KMS). I specified the KMS key material origin as external, chose RSAES_OAEP_SHA_256 as the algorithm for the wrapping key, and then 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?

Short description

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 KMS key 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.

Resolution

Create a KMS key using External for the key material origin

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

Note:

export REGION=us-east-1
export KEY_ALIAS=kms_key_with_externalmaterial
export KEY_ID=`aws kms create-key --region $REGION --origin EXTERNAL --description $KEY_ALIAS --query KeyMetadata.KeyId --output text`
aws kms --region $REGION create-alias --alias-name alias/$KEY_ALIAS --target-key-id $KEY_ID

Your newly created KMS key status is Pending Import 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 then store these values 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 | awk '{print $7}' | tr -d '",' | base64 --decode > PublicKey.bin
echo $KEY_PARAMETERS | awk '{print $5}' | tr -d '",' | base64 --decode > ImportToken.bin

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

-or-

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.

Important: 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 Amazon Elastic Compute Cloud (Amazon 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.    To update OpenSSL, 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 that 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. You import this value as the encrypted key material into the KMS.

Import your encrypted key material

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

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 completes, 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

Related information

About imported key material

AWS OFFICIAL
AWS OFFICIALUpdated 2 years ago