1

I am trying to decrypt a string with AWS KMS, but I am getting an InvalidCiphertextException error (with no further information following the exception name).

I was originally decrypting in a node js lambda, using an environment variable as the source for encryptedString:

var params = {
    CiphertextBlob: Buffer.from(encryptedString, 'base64')
};
kms.decrypt(params, function(err, data) {
    if (err) {
        ...
    } else {
        ...
    }
}

I have also tried it with the CiphertextBlob value as a String, i.e.:

CiphertextBlob: encryptedString

The KMS key used to encrypt the value originally is a symmetric CMK so I believe I shouldn't need to pass in the key ID.

I also tried the same thing via awscli (passing in ciphertext-blob as a string) but got the same error:

aws kms decrypt --ciphertext-blob <encrypted string value> --query PlainText | base64 --decode

Passing in the key ID had no effect either.

I have used an online tool to validate that the encrypted string is base64. I'm not too clued up on base64 encoding so not sure if that's all it takes to prove the cipher text is valid.

I'm sure I'm failing with something fundamental - either my encrypted string is not base64 or not what decrypt expects, or I am missing some additional decrypt arguments perhaps.

Thanks in advance.

Neil
  • 413
  • 4
  • 22
  • Is there any [encryption context](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context) associated with your secret? If there is, you need to specify it as well to decrypt your secret. – Marcin Sep 05 '20 at 09:39
  • No I can't see any - I've checked the key policy and there are no Condition fields specifying kms:EncryptionContext. – Neil Sep 05 '20 at 10:50
  • Did you encrypt the secret yourself using KMS? The encryption context is given during encryption procedure. If you provided it at that time, it must be provided at the decryption as well. key policy does not change this. – Marcin Sep 05 '20 at 10:53
  • 1
    No the key already exists, it was created some time ago so I don't have access to any creation details, as far as I know. Is there any way to see what encryption context was passed at creation? – Neil Sep 05 '20 at 11:02
  • The encryption context is not a secret. If you have CloudTrial enabled, the encryption context will be listed there for the event corresponding to encrypt operation. I'm not saying that the encryption context is definitely the root cause of your issue, but its a possibility worth exploring if you are running out of ideas. – Marcin Sep 05 '20 at 11:09
  • 1
    I've created a brand new KMS key, and a new SSM param using that key. I've then passed the encrypted string to a lambda environment variable and tried decrypting with the above commands both in the lambda and via awscli, but still get the same error. I checked the CloudTrail CreateKey event but couldn't see any encryption context related information (as expected, as I did not specify any encryption context when I created the new key). – Neil Sep 07 '20 at 12:04
  • Oh. This is SSM parameter?. Should have said it earlier. I could tell you immediately you need the encryption context to decrypt it :-) – Marcin Sep 07 '20 at 12:38
  • I am storing the encrypted ssm parameter string in a lambda environment variable, and then at lambda runtime I'm trying to decrypt the string. But I can't tell what encryption context would have been used to create the ssm param (and didn't specify any context on the param I created myself to test). – Neil Sep 07 '20 at 12:52
  • I provided the answer with the encryption context that is used by SSM parameters. You can check it out. You have to provide it if you "manually" want to decrypt ssm securestring parameter using KMS api. – Marcin Sep 07 '20 at 12:54

1 Answers1

2

Based on the comments.

The issue is with decrypting SSM parameter. Thus, an encryption context must be provided during the decryption procedure. From docs:

Parameter Store includes this encryption context in calls to encrypt and decrypt the MyParameter parameter in an example AWS account and region.

"PARAMETER_ARN":"arn:aws:ssm:<REGION_NAME>:<ACCOUNT_ID>:parameter/<parameter-name>"

Therefore, if you are not using get_parameter with WithDecryption option set to True, you must provide the above encryption context during KMS decrypt operation.

Marcin
  • 215,873
  • 14
  • 235
  • 294