0

I am trying to multi-part upload a file using Amazon S3 Server side encryption(KMS). I am getting a little confused whether I do need the KMS key in my code anywhere and if so, then how do I add it to the Java code?

--Update private static void saveMultipartData(String clientRegion, String bucketName, String awsFilePath, File file) { AmazonS3 s3client = AmazonS3Client.builder() .withRegion(clientRegion) .withCredentials(new AWSStaticCredentialsProvider(credentials)) .build();

    ObjectMetadata objectMetadata = new ObjectMetadata();
    PutObjectRequest putRequest = null;
    try {
        try {
            putRequest = new PutObjectRequest(bucketName,
                    awsFilePath,
                    new FileInputStream(file),
                    objectMetadata);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        // Upload the object and check its encryption status.
        putRequest.putCustomRequestHeader("x-amz-server-side-encryption","aws:kms");
        putRequest.putCustomRequestHeader("x-amz-server-side-encryption-aws-kms-key-id","<<keyID>>");

        TransferManager tm = TransferManagerBuilder.standard().withMinimumUploadPartSize(100L).withMultipartUploadThreshold(100L)
                .withS3Client(s3client)
                .build();
        Upload upload = tm.upload(putRequest);

        upload.waitForCompletion();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
user3115056
  • 1,266
  • 1
  • 10
  • 25

1 Answers1

2

While you don't need to have the KMS key in your code, your code does need to be able to access the key. What I am implying is that you, for example, use an environment variable to pass this value in- that way the key is hidden. Once you have the key, doing a multi-part upload can be performed as this:

InitiateMultipartUploadRequest initRequest = new
                InitiateMultipartUploadRequest(bucketName, keyName);
        initRequest.putCustomRequestHeader("x-amz-server-side-encryption", "aws:kms");
        initRequest.putCustomRequestHeader("x-amz-server-side-encryption-aws-kms-key-id", kmsKey);
ketcham
  • 922
  • 4
  • 15
  • Thanks for the response. However I am pretty novice in this area. I am actually using the code(updated in the question) taking some idea from your response. Using high level multi-part upload. However not sure but when I download the file from S3, it doesn't show an encrypted file. Under the overview of the file I am able to see KMS-Encrypted, but file when downloaded shows the content of the file unencrypted.. – user3115056 Jul 25 '19 at 17:34
  • That's a good sign that you see KMS-Encrypted. What you described is normal behavior-- you're downloading the file as a user that is likely authorized to decrypt. If you want to see what it looks like to get the raw file (encrypted), try performing a cli command using a role that isn't permitted to decrypt. More on this here: https://aws.amazon.com/premiumsupport/knowledge-center/decrypt-kms-encrypted-objects-s3/ – ketcham Jul 25 '19 at 17:53
  • Wonderful. Thanks for you help..:) – user3115056 Jul 25 '19 at 17:55