Home > database >  How do I decrypt a file encrypted with S3 REST API
How do I decrypt a file encrypted with S3 REST API

Time:03-10

I'm using REST encryption for files uploaded to Amazon S3 as specified in official doc in section Using the REST API by adding x-amz-server-side-encryption header with a value of aws:kms to uploading request.

Then on Java side, I use the following code to access the uploaded file:

private AmazonS3 client;
private String s3BucketName;
private String uploadedImportPathPrefix;

public Reader readFile(String storeId, String fileName) {
    String filePath = uploadedImportPathPrefix   "/"   storeId   "/"    fileName;
    S3Object s3Object = client.getObject(s3BucketName, filePath);
    S3ObjectInputStream s3is = s3Object.getObjectContent();
    Reader reader = new InputStreamReader(s3is);
    return reader;
}

What is still unclear to me is the way to decrypt the file on Java side. Any suggestions?

CodePudding user response:

I am going to answer this using the AWS SDK for Java V2 (not V1 or Rest). This will still point you in the right direction.

To decrypt data retrieved from an Amazon S3 bucket using KMS, you need the key id used to encrypt the data. Here is a Java V2 example that shows this use case:

// Decrypt the data passed as a byte array
  private static byte[] decryptData(byte[] data, String keyId) {

    try {
        KmsClient kmsClient = getKMSClient();
        SdkBytes encryptedData = SdkBytes.fromByteArray(data);

        DecryptRequest decryptRequest = DecryptRequest.builder()
                .ciphertextBlob(encryptedData)
                .keyId(keyId)
                .build();

        DecryptResponse decryptResponse = kmsClient.decrypt(decryptRequest);
        SdkBytes plainText = decryptResponse.plaintext();
        return plainText.asByteArray();

    } catch (KmsException e) {
        System.err.println(e.getMessage());
        System.exit(1);
    }
    return null;
}

Full Amazon S3 and KMS AWS SDK for Java V2 example here.

You still need the key ID when using V1 (which is not best practice).

CodePudding user response:

To download an S3 object that was encrypted with KMS, you need kms:Decrypt permission on the relevant KMS key.

Here's an example of a policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "p1",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::mybucket/*"
      ]
    },
    {
      "Sid": "p2",
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt"
      ],
      "Resource": [
        "arn:aws:kms:region:123456789012:key/kms-key-id"
      ]
    }
  ]
}

PS not sure what you mean by "REST encryption". Perhaps you mean "encryption at rest"?

  • Related