Encryption max data size allowed for AWS KMS is 4kb, so whenever we use encryption in AWS services/resources is Encryption done using envelope encryption? , i.e, data is encrypted at resource side itself with the key and key is encrypted with another key(cmk)and stored along with the data and decryption happens in the reverse order of above steps. Is my understanding correct??
3 Answers
Probably. It seems to be at least true for S3:
Server-side encryption protects data at rest. Amazon S3 encrypts each object with a unique key. As an additional safeguard, it encrypts the key itself with a master key that it rotates regularly. Amazon S3 server-side encryption uses one of the strongest block ciphers available to encrypt your data, 256-bit Advanced Encryption Standard (AES-256).
Generally the CMK is not used for encrypting the data that you are looking to encrypt.
Whilst it’s a matter of opinion on the 4kb limit, data encryption keys provide a more secure approach to encrypting the data.
Because each resource could have its own data encryption key, the risk is reduced of having all of your resources decrypted if a single encryption key is compromised (in fact if this happens KMS supports re encryption to generate a new data key).
What you describe is correct for S3 implementation of KMS. A Base64 encoded encrypted key is stored alongside the object it encrypts. To decrypt S3 needs to decrypt the data key for the object using the CMK, then use the decrypted data encryption key to decrypt the object.
Other services will have different implementations, for example DynamoDB does this on a per table basis.
For more information on how each service has implemented KMS take a look at the How AWS Services use AWS KMS page
Aws kms does not store any data it provide you two keys
1 plain key : with the help of it you encrypt the data and delete it(key)(no need to save anywhere).
2.encrypted data key :- you need to save this key to decrypt the data( to decrypt the data first you got plain key from aws using encrypted data key) and with the help of plain key you decrypt the data.
Note you need aws kms credentials like :-
a)serviceEndPoint b)awsKeyForKMS c)kmsConfig
KMS Encryption and Decryption in asp.net mvc
Name space need to add from nuget packeg
using Amazon.KeyManagementService;
using Amazon.KeyManagementService.Model;
**1) Encryption :-**
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);
GenerateDataKeyRequest dataKeyReq = new GenerateDataKeyRequest();
dataKeyReq.KeyId = keyARNForKMS;
dataKeyReq.KeySpec = DataKeySpec.AES_256;//The length of the data encryption key. AES_256 to generate a 256-bit symmetric key.
GenerateDataKeyResponse dataKeyResponse = kmsClient.GenerateDataKey(dataKeyReq);
//read encrypted data key from memory
MemoryStream streamCipherText = dataKeyResponse.CiphertextBlob;
// need to save this key with encrypted data because with the help of it
// you can decrypt(you got plaindatakey) the data
encryptedDataKey = Convert.ToBase64String(streamCipherText.ToArray());
//read plain data key from memory
MemoryStream streamPlainText = dataKeyResponse.Plaintext;
// use this key to encrypt your data and than forgot this key
plainDataKey = Convert.ToBase64String(streamPlainText.ToArray());
//your encryption logic
Encryption encrypt = new Encryption();
encrypt.EncryptTextForKms(PlainKey, "data to be encrypted")
**2.Decryption Data:-**
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 decryptResp = kmsClient.Decrypt(decryptRequest);
plainDataKey = Convert.ToBase64String(decryptResp.Plaintext.ToArray());
// your decryption logic
DecryptTexts("encrypted data", PlainKey)