2
votes

I am using Amazon aws Java SDK for coding.

I have uploaded few of my local files to S3 by using SSE-C(server side encryption using customer provided key) and few files without using any encryption. Before downloading a file in some other module, I need to make sure whether that particular file is encrypted or not. I have referred this link. But this procedure is for files encrypted with SSE (which is different to SSE-C). After referring to Amazon aws Java APIs I have written below code.

Base64 b = new Base64();
byte[] keyBytes = b.decode("encryptionKey");
SecretKey key = new SecretKeySpec(keyBytes,0,keyBytes.length,"AES");
SSECustomerKey sseKey = new SSECustomerKey(key);

GetObjectMetadataRequest request2 =new GetObjectMetadataRequest("bucketname","keyname").withSSECustomerKey(sseKey);
ObjectMetadata metadata = s3client.getObjectMetadata(request2);
System.out.println("Encryption algorithm used: " + metadata.getSSECustomerAlgorithm());

The above piece of code is working fine to download an encrypted file. But giving exception while downloading file which was not encrypted.

Is there any common API to get the metadata of both encrypted and non encrypted files.

2
You shouldn't need the key to retrieve the metadata, as the docs say metadata is not encrypted. Does it work if you remove the .withSSECustomerKey(sseKey) part? - augurar
I am getting Bad Request 400 if i remove encryption key part - Durgesh
Hmm, I guess this doc does say you need the SSEC key even for metadata. So you'll need to either catch the exception and retry with/without the key, or come up with some other way of recording which files are encrypted. - augurar

2 Answers

1
votes

You can run the check before, and if getSSECustomerKey returns null, you know it has not been encrypted, something like

GetObjectMetadataRequest request2 = new GetObjectMetadataRequest("bucketname","keyname");
ObjectMetadata metadata = s3client.getObjectMetadata(request2);

if (metadata.getSSEAlgorithm() == null) {
    // download files directly - it is not encrypted
} else {
    // files encrypted - add the SSE key
}

The other option is to check exception and treat download of non-crypted file in the exception, do a check if the file exists and do download.

1
votes

The general guidance when using SSE-C is to separately store a mapping between S3 objects and which encryption key was used (not the key itself though). This mapping could be stored in a database (RDS, Dynamo, even SimpleDB). Or it could even be in S3: store a file in a path like .../metadata/<object> that contains the key ID or "NONE", and read that before you try to GET the actual file.

One reason to do it this way is to support multiple customer keys. You might need to gradually transition from one key to another because of a key rotation policy, or decide to use a different key for each of your customers. This way, your app is ready to support any of these scenarios.