I want to use AWS Key Management Service (AWS KMS) to sign a file. Then, I want to share the file, its signature, and the public key for verification that the signature is valid. I don't want to provide API access for users to access my AWS KMS key.
Resolution
The following example uses AWS KMS with an ECC_NIST_P256 (secp256r1) asymmetric key pair. When AWS KMS uses this key pair to generate a signature file, the file is created according to NIST FIPS 168-4. An ECDSA digital signature that contains (r, s) values is generated as specified in ANS X9.62. Because of the open standard, you can use OpenSSL to verify the signature.
To get the signature format for RSA key pairs, see RSA key specs for signing and verification.
Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.
Sign a local file
After you create the AWS KMS asymmetric key in your AWS account, use the AWS CLI to refer to the key when you sign a file. The response you receive from the AWS KMS API is encoded in base64. The following example uses the --query parameter to get the signature value from the response and place it in the sign.b64 file:
[ec2-user@ip-172-31-23-22 ~]$ aws kms sign --key-id arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab --message fileb://message.txt --signing-algorithm ECDSA_SHA_256 --query 'Signature' --output text > sign.b64
Note: You can submit messages up to 4096 B. To sign a larger message, generate a hash digest of the message. Then, provide the hash digest in the message parameter. To show whether the message is a full message or a digest, use the MessageType parameter. Note the signing algorithm to verify the signature later.
Because the signature is in base64 format, run the following Linux base64 encoding command to convert the format to binary:
[ec2-user@ip-172-31-23-22 ~]$ base64 -d sign.b64 > sign.bin
Run the following command to decode base64 files for Windows operating system (OS):
certutil -decode C:\Temp\sign.b64 C:\Temp\sign.bin
You can now share the sign.b64 signature file.
Verify the AWS KMS signature
To verify the signature file, you must have the public key. To get the public key, run the get-public-key AWS CLI command:
[ec2-user@ip-172-31-23-22 ~]$ aws kms get-public-key --key-id arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab --output text --query 'PublicKey' > KMSPublic.b64
Run the following command to convert the base64 file to a DER-encoded file that's named KMSPublic.key:
[ec2-user@ip-172-31-23-22 ~]$ base64 -d KMSPublic.b64 > KMSPublic.key
You now have the public key and signature in binary format with the message.txt file.
To verify the signature, run the dgst OpenSSL command:
[ec2-user@ip-172-31-23-22 ~]$ openssl dgst -sha256 -verify KMSPublic.key -keyform DER -signature sign.bin message.txtVerified OK
The verification is successful when the output shows "Verified OK".
If you don't receive a verification response, then check the following:
- The OpenSSL signature algorithm is the same one that you used to sign the file.
- Your files aren't base64 encoded.
Related information
Cryptographic primitives
AWS KMS concepts