Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error while decrypting file using KMS key in Amazon S3

I am trying to use Amazon S3 as a file system with encryption.

I am successfully able to achieve uploading file on AWS S3 server using KMS Encrypted key (Server side Encryption). Please find below working code :

For Encrypt:

private static final String AWS_KMS_KEY = "---KMS Key---"
private static final String BUCKET_NAME = "---bucket name---"
private static final String keyName = "---display key name---"
private static final String filePath = "---File Path---"
private static final String ACCESS_KEY_ID = "---aws accesskey---"
private static final String SECRET_ACCESS_KEY = "---aws secret key---"

AWSCredentials awsCredentials = new BasicAWSCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
    .withRegion(Regions.US_WEST_2).withForceGlobalBucketAccessEnabled(true).build();

FileInputStream stream = new FileInputStream(filePath);

ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setSSEAlgorithm(SSEAlgorithm.KMS.getAlgorithm());

PutObjectRequest putObjectRequest = new PutObjectRequest(amazonFileUploadLocationOriginal, keyName, stream, objectMetadata);
putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead);
putObjectRequest.withSSEAwsKeyManagementParams(new SSEAwsKeyManagementParams(AWS_KMS_KEY));

PutObjectResult result = s3Client.putObject(putObjectRequest);

I am facing issue while retriving file with server side decryption. I want to access directly aws url to retrieve that file with decryption. Please find below code which is not working :

For object read :

Object Read without KMS key :

GetObjectRequest request = new GetObjectRequest(existingBucketName, amazonFileUploadLocationOriginal);
s3Client.getUrl(BUCKET_NAME, keyName); 

Above Code is for read object without kms encrypted key which shows below error.

Code : InvalidArgument

Message : Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.


Object Read with KMS key :

GeneratePresignedUrlRequest genreq = new GeneratePresignedUrlRequest(BUCKET_NAME, keyName, HttpMethod.GET)
            .withSSEAlgorithm(SSEAlgorithm.KMS)
            .withKmsCmkId(AWS_KMS_KEY);

URL puturl = s3Client.generatePresignedUrl(genreq);

Above Code is for read object with kms encrypted key presign URL, which shows below error.

Code : SignatureDoesNotMatch

Message : The request signature we calculated does not match the signature you provided. Check your key and signing method.

Is it right way to do? Is there any suggestions? Please help.

like image 615
Jaimin Darji Avatar asked Jun 29 '17 06:06

Jaimin Darji


1 Answers

if the signature not match please use the following code to add manually for reference AWS java SDK manually set signature version

System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");

We can use the below code to get presided URL get

GeneratePresignedUrlRequest genreq = new GeneratePresignedUrlRequest(BUCKET_NAME, keyName, HttpMethod.GET)
 .withExpiration(expiration);

URL puturl = s3Client.generatePresignedUrl(genreq);

This URL will contain the expiry of time and signature like following

output

https://mybucket.s3.amazonaws.com/abc_count.png?AWSAccessKeyId=AKIAJXXXXXXXXXXXXXXX&Expires=1503602631&Signature=ibOGfAovnhIF13DALdAgsdtg2s%3D

Hope some one helps this ans

like image 101
Jaimin Darji Avatar answered Oct 28 '22 14:10

Jaimin Darji