AWS S3 SSE GetObject Requires Private Key

The idea was to generate a random key for each file uploaded, pass that key to S3 to encrypt it and store the key in the database. As soon as the user wants to access the file, the key is read from the database and sent back to S3.

The first part works. My objects have loaded and encrypted successfully, but I am having problems retrieving them.

Getting files with request headers:

When customizing request headers like x-amz-server-side-encryption-customer-algorithm

etc. when making a GET request to the resource, it works and I can access it. But since I want to use these resources src

for both <img>-Tag

, I cannot make GET requests that require headers to be set.

Thus, I was thinking about:

Pre-signed URLs:

To create a pre-signed url, I built the HMAC SHA1 of the required string and used it as the signature. The computed signature is accepted by S3, but when requesting the pre-signed URL, I get the following error:

Requests specifying server-side encryption with Client-supplied keys must provide the appropriate secret key.

The url is of the form:


The reason the error is displayed seems pretty clear to me. Under no circumstances was an encryption key used during the signing process. So the request cannot work. As a result, I added the encryption key as Base64 and Md5 as URL parameters. The URL now has the following format:


Although the (imho) key is now present, I am getting the same error message.

Question Does anyone know how I can access my encrypted files with a request GET

that does not contain headers like x-amz-server-side-encryption-customer-algorithm



source to share

1 answer

It seems intuitive enough to me that what you are trying should work.

Apparently, though, when they say "headlines" ...

you must provide all encryption headers in your client application.


... they really do mean headers , and S3 does not accept these specific values ​​when delivered as part of the query string, as you would expect, since S3 is sometimes somewhat flexible in this regard.

I tested this and concluded that doing this is not supported.


request with x-amz-server-side-encryption-customer-algorithm=AES256

included in the query string (and signature) along with the headers X-Amz-Server-Side-Encryption-Customer-Key

and X-Amz-Server-Side-Encryption-Customer-Key-MD5

works as expected ... as I believe you discovered ... but put the key and key-md5 in the query string, with or without inclusion in the signature looks like a dead end.

At first it seemed odd that they would not allow this in the query string, since a lot of other things are allowed there ... but then again, if you are facing a problem with encrypting something, there seems to be little point in revealing the encryption key in the link ... not to mention that this key would then be written to the S3 access logs, leaving encryption seemingly pretty pointless around - and perhaps that was their motivation for claiming it was actually sent in the headers rather than the query string.

However, based on what I found in testing, I don't see a way to directly use encrypted objects with client supplied keys in hyperlinks.

Indirectly, of course, a reverse proxy in front of the S3 bucket could do the translation for you by taking the appropriate values ​​from the query string and putting them in the headers instead ... but it's really not clear to me what can be obtained with client-supplied encryption keys for the objects being loaded compared to letting S3 handle encryption non-stop with AWS-managed keys. Extensive encryption is all you get anyway.



All Articles