Sign and Encrypt data over 4KB using AWS KMS Keys

AWS KMS allows the creation of cryptographic keys that can be used to encrypt data. Users can create symmetric or asymmetric keys for various different data encryption scenarios. For example, symmetric KMS keys can be used to encrypt and decrypt data, or to generate and verify hashes. The various Key Usage properties for symmetric and asymmetric keys can be reviewed in the KMS documentation.

Whether a user is performing the Encrypt or Sign API’s, there is a size constraint for the data that can be encrypted. These commands will only accept data up to 4,096 bytes (4KB). For example, let’s see what happens when I attempt the encrypt operation on a file larger than 4KB.

Note: All the commands I ran in this article can be found in my Github

Scenario 1: Across columns

As we can see in the screenshot above, there are two files. The ‘under4KB’ file is only 12 bytes, while the ’test’ file is 33KB. The encrypt command works as expected on ‘under4kb’, but when running this command on ’test’ we get the following error:

    An error occurred (ValidationException) when calling the Encrypt operation: 1 validation error detected: Value at 'plaintext' failed to satisfy constraint: Member must have length less than or equal to 4096

   

To perform the Encrypt command with data that is over 4KB, we can create a message digest for files over 4KB. Using openSSL I created a message digest of ’test’ with the following command:

openssl dgst -sha256 -binary -out message_digest_test test

This command creates a message digest named ‘message_digest_test’ of the ’test’ file using the sha256 algorithm. If we take a look at the file size of ‘message_digest_test’ we see it is now under 4KB, and the encrypt command works on it as expected:

Scenario 1: Across columns

   

Now we will create an Asymmetric KMS key that can be used for creating and verifying digital signatures. I made an Asymmetric Sign/Verify KMS key that uses the RSA_2048 Algorithm. The key was created with the following create-key command:

aws kms create-key --key-usage SIGN_VERIFY --key-spec RSA_2048

The –key-usage and –key-spec parameters are optional. The create-key command will create a symmetric encrypt/decrypt key by default. When the –policy parameter is not used, the default KMS key policy will be attached to the created key.

The default KMS Key Policy will allow any principal in the account that created the key access to the key, provided their IAM permissions allow the action.

Say, for example, UserA has the following KMS permissions in their IAM policy:

  • kms:DescribeKey
  • kms:Encrypt

UserA will be able to perform the DescribeKey and Encrypt actions with a key that has the default KMS key policy. However, UserA will not be able to perform the Decrypt action or any other KMS actions until they are added to UserA’s IAM permissions.

   

If I perform the sign command on ‘under4KB’, we successfully create a digital signature with our new key. However, when we attempt this on our larger file, ’test’, it fails with the same error we received before:

Scenario 1: Across columns

When I try this same command using our message digest, we get a digital signature for ‘message_digest_test’. We can use the verify command to confirm the digital signature was created by our asymmetric key. Be sure to pass the signature in the verify command with the –signature parameter:

Scenario 1: Across columns

The verify command requires the base64 decoded version of the signature that is provided. This is why we include both the original message, which is decoded, and the encoded signature when running the command.    

Working around size constraints can be a headache. Thanks to free tools like openssl, message digests can be used to ensure that data of any size can be encrypted using the KMS keys of your choice!