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
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
Working with Message Digests
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:
Creating an Asymmetric Sign/Verify Key
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.
Working with the Sign API
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:
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:
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.
Conclusion
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!