Hot questions for Using Amazon S3 in aws kms

Question:

I'm using the awssdk v2: https://sdk.amazonaws.com/java/api/latest/

I want to put objects in S3 using a customer-managed KMS key for encryption at rest, I'm using sse-c to achieve this. However, it seems to always default to the AWS managed key as opposed to the customer managed one.

Following is my code:

PutObjectRequest putObjectRequest =
    PutObjectRequest.builder()
        .bucket(bucket)
        .key(key)
        .serverSideEncryption(ServerSideEncryption.AWS_KMS)
        .ssekmsKeyId(this.s3KmsKeyId) // my key alias
        .build();

s3Client.putObject(putObjectRequest, RequestBody.fromString(data)); // data = some string value

I am using PutObjectRequest to configure my request and S3Client to send it off to S3.

Since the keys are set to rotate, I cannot use an arn or the keyId itself. I also can't seem to find an example of how this can be achieved using this sdk.


Answer:

To be able to retrieve a KMS Key Id from KMS you need to make use of the KmsClient. sseKmsKeyId will not accept an alias, because it is not able to figure out the Key ID using the alias.

You can do something like the following:

KmsClient kmsClient = KmsClient.builder().build();
DescribeKeyRequest req = DescribeKeyRequest.builder().keyId("alias/your_kms_alias").build();
DescribeKeyResponse res = kmsClient.describeKey(req);

// See https://docs.aws.amazon.com/kms/latest/APIReference/API_DescribeKey.html
// For the response you will get back from DescribeKey

// Then create the request to S3

PutObjectRequest putObjectRequest =
    PutObjectRequest.builder()
        .bucket(bucket)
        .key(key)
        .serverSideEncryption(ServerSideEncryption.AWS_KMS)
        .ssekmsKeyId(res.keyMetadata().keyId()) // the actual keyId from KMS CMK
        .build();

s3Client.putObject(putObjectRequest, RequestBody.fromString(data));

See also: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kms/model/DescribeKeyRequest.html#keyId--

If you specify a predefined AWS alias (an AWS alias with no key ID), KMS associates the alias with an AWS managed CMK and returns its KeyId and Arn in the response.

Hope that helps.