I'm attempting to encrypt data using KMS and the AWS Encryption SDK. Looking at the example provided in the AWS documentation, it appears that there is nowhere to explicitly set the data key.
I've found API documentation for the EncryptionMaterialsRequest
class that allows you to set the plaintext key using the associated builder class, EncryptionMaterialsRequest.Builder
, and this class has a method that returns an instance of EncryptionMaterials
. I can't find anywhere to use the EncryptionMaterials
instance when executing the encrypt operation.
Here is the code I have so far. Note that the EncryptionMaterials
instance isn't used in the request.
public static void encryptData(String dataToEncrypt, String keyID) {
final KmsMasterKeyProvider prov = new KmsMasterKeyProvider(keyID);
DefaultCryptoMaterialsManager manager = new DefaultCryptoMaterialsManager(prov);
byte[] plaintextKey = generateDataKey(keyID);
EncryptionMaterialsRequest request = EncryptionMaterialsRequest
.newBuilder()
.setPlaintext(plaintextKey)
.build();
EncryptionMaterials materials = manager.getMaterialsForEncrypt(request);
AwsCrypto crypto = new AwsCrypto();
String encryptedString = crypto.encryptString(manager, dataToEncrypt).getResult();
}
public byte[] generateDataKey(String keyID) {
GenerateDataKeyRequest dataKeyRequest = new GenerateDataKeyRequest();
dataKeyRequest.setKeyId(keyID);
dataKeyRequest.setKeySpec(DataKeySpec.AES_256);
GenerateDataKeyResult dataKeyResult = kmsClient.generateDataKey(dataKeyRequest);
ByteBuffer encryptedKey = dataKeyResult.getCiphertextBlob();
byte[] arr = new byte[encryptedKey.remaining()];
encryptedKey.get(arr);
return arr;
}
What is the recommended approach encrypting data using the AWS Encryption SDK with a data key generated by KMS?
@Viccari is correct, but it sounds like some context around the intended use of these constructs would help explain why.
Unless you are building a custom cryptographic materials manager you should not be creating EncryptionMaterials
; the client and management components take care of that for you.
The client asks the cryptographic materials manager for encryption materials on every encrypt call. Depending on the cryptographic materials manager, what exactly happens next might be different.
In the case of the DefaulCryptoMaterialsManager
, it then asks the provided master key provider for all of the master keys to use, then uses those master keys to generate and encrypt the data key (one is used to generate and encrypt, any additional are used to encrypt).
In the case of the CachingCryptoMaterialsManager
, it adds a caching layer between the client and another cryptographic materials manager.
If you want to use the AWS Encryption SDK with AWS KMS, the recommended approach is to simply provide an instance of KmsMasterKey
or KmsMasterKeyProvider
, or a cryptographic materials manager that ultimately uses one of those, in the encrypt call. All of the details are taken care of by the client.
If you're interested in more details about how these concepts fit together, our concepts documentation[1] would be a good place to start.
[1] https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html