2
votes

I am a little confused as to how a cipher text blob is decrypted with the AWS KMS client. Here is an example from the AWS Docs:

// Encrypt a data key
//
// Replace the following fictitious CMK ARN with a valid CMK ID or ARN
String keyId = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd- 
56ef-1234567890ab";
ByteBuffer plaintext = ByteBuffer.wrap(new byte[]{1,2,3,4,5,6,7,8,9,0});

EncryptRequest req = new 
EncryptRequest().withKeyId(keyId).withPlaintext(plaintext);
ByteBuffer ciphertext = kmsClient.encrypt(req).getCiphertextBlob();

// Decrypt a data key
//

ByteBuffer ciphertextBlob = Place your ciphertext here;

DecryptRequest req = new DecryptRequest().withCiphertextBlob(ciphertextBlob);
ByteBuffer plainText = kmsClient.decrypt(req).getPlaintext();

No KMS key is provided in the decrypt method. Does that mean somehow the KMS key is encrypted in the cyphertext blob? If so...

  • how are the permissions granted to decrypt the encrypted ciphertext blob?
  • If I wanted to decrypt a value from an AWS service, do I create an IAM role to do so and configure the KMS Key to allow that role to decrypt?
3

3 Answers

1
votes

Your examples is from Encrypting and Decrypting Data Keys:

These operations are designed to encrypt and decrypt data keys. They use an AWS KMS customer master key (CMK) in the encryption operations and they cannot accept more than 4 KB (4096 bytes) of data. Although you might use them to encrypt small amounts of data, such as a password or RSA key, they are not designed to encrypt application data.

CMKs:

are created in AWS KMS and never leave AWS KMS unencrypted. To use or manage your CMK, you access them through AWS KMS.

These operations are all using configured master keys from your AWS setup, rather than keys that are provided dynamically. Use AWS Management Console to manage these keys.

When using the encrypt method, the key ID is stored in the response:

{
   "CiphertextBlob": blob,
   "KeyId": "string"
}

It will be used during decryption.

0
votes
AmazonKeyManagementServiceConfig kmsConfig = new AmazonKeyManagementServiceConfig();
            kmsConfig.UseHttp = true;
            kmsConfig.ServiceURL = serviceEndPoint;
                //create client, specify Region end point or kms config
                AmazonKeyManagementServiceClient kmsClient = new AmazonKeyManagementServiceClient(awsKeyForKMS, awsSecretKeyForKMS, kmsConfig);
                DecryptRequest decryptRequest = new DecryptRequest();
// use hare above created encrypteddatakey to get plaindatakey
                MemoryStream streamEncryptedDataKey = new MemoryStream(Convert.FromBase64String(encryptedDataKey));//convert to stream object
                decryptRequest.CiphertextBlob = streamEncryptedDataKey;
                DecryptResponse decry`enter code here`ptResp = kmsClient.Decrypt(decryptRequest);
                plainDataKey = Convert.ToBase64String(decryptResp.Plaintext.ToArray());
// your decryption logic
             DecryptTexts("encrypted data", PlainKey)
0
votes

For the purposes on this answer, I am assuming you are using an AWS KMS CMK with symmetric encryption.

When using symmetric keys, the content of the cyphertext block does include which KMS key was used to encrypt it. See more about that here: https://docs.aws.amazon.com/kms/latest/developerguide/programming-encryption.html#decryption They still note you should specify a key to decrypt it, but isn't needed since it is in the cyphertext blob.

However, the presence of that key id doesn't grant any permissions to use that key for decrypting anything. You can have a user/entity that is permitted to encrypt things with no permission to decrypt with that key, including the message they just encrypted. You can control who has access to the decrypt function through two different ways.

The first is the 'Key Policy'. Key policies always 'win' are the first policy consulted when evaluating if an access is permitted. By default, the Key Policy is setup to say 'allow whoever to use this key that is permitted to by IAM'. (BTW, IAM is the second way of getting access, but only if the Key Policy allows it to be delegated to for that key). Key Policies only apply to the key they are applied to (even if the resource field is '*'). Key policies can grant access to specific entities/users/accounts and/or delegate to IAM. You can read more about the default key policy here: https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default

The second is IAM, where you are likely more familiar with in the general account permissions. This is where you can also grant access to kms:decrypt to policy statements and resources you wish it to be applied to.

However, back to your original questions:

how are the permissions granted to decrypt the encrypted ciphertext blob?

Through access to the kms:decrypt permission, either through the Key Policy or IAM (when delegation to IAM is enabled in the Key Policy).

If I wanted to decrypt a value from an AWS service, do I create an IAM role to do so and configure the KMS Key to allow that role to decrypt?

It doesn't matter who created the key, if a data element is protected by a KMS key, that key needs to be granted access to kms:decrypt. (Exception: some AWS services need grants, like EBS, instead of kms:decrypt due to low level technical issues, but the same principle applies). Make sure that the key policy has the IAM delegation enabled, and then feel free to attach a policy to a IAM role which permits access to kms:decrypt for that key to get access to decrypt operations for that user/entity which has that role. Of course, you needed to give permission to AWS to encrypt using that Key in the first place (and that is done through the Key Policy where the principal is an AWS service), but I assume you already did that since your question is about decrypt.