Reputation: 21
I uploaded encrypted object using server-side encryption with customer-provided keys (SSE-C). Is it possible to download an object using pre-signed URL in AWS S3?
I tried like this
GeneratePresignedUrlRequest generatePresignedUrlRequest1 = new GeneratePresignedUrlRequest("bucketname", "objectpath")
.withMethod(HttpMethod.GET)
.withSSECustomerKey(new SSECustomerKey("base64mykey"))
.withExpiration(new Date( System.currentTimeMillis() + (60 * 60 * 1000)));
The link is generated but when accessing it in the browser I'm getting this error The request signature we calculated does not match the signature you provided. Check your key and signing method.
Is there a solution for this?
Upvotes: 0
Views: 1813
Reputation: 31
Ok but with a curl lime this:
curl -v -T ${S3_UPLOAD_FILE} https://$S3_BUCKET.s3.amazonaws.com/${S3_DESTINATION_FILE} -H "Date: ${S3_DATE}" -H "Authorization: AWS ${S3_KEY}:${S3_SIGNATURE}" -H "Content-Type: ${S3_CONTENT_TYPE}" -H "Content-MD5: ${S3_MD5SUM}" -H "x-amz-server-side-encryption-customer-algorithm:${S3_SSEC_ALGORITHM}" -H "x-amz-server-side-encryption-customer-key:${S3_ENCRYPTION_KEY}" -H "x-amz-server-side-encryption-customer-key-MD5:${S3_ENCRYPTION_MD5}"
I can upload a file ro an s3 bucket with sse-c key. Wath about download?
Upvotes: 0
Reputation: 179404
SSE-C with pre-signed URLs may not work the way you expect.
The input to the request-signing algorithm includes all headers that begin with x-amz-*
. This is significant for a reason that will become clearer in a moment.
The signature-generating code needs to know what these values will be when you actually make the request, and that is the only thing .withSSECustomerKey()
does -- provides information that the signing algorithm needs so that the signature matches the actual request you eventually send.
The encryption key isn't actually embedded in the pre-signed URL. It needs to be supplied a second time, when the request is actually made.
When using server-side encryption with customer-provided encryption keys (SSE-C), you must provide encryption key information using the following request headers.
x-amz-server-side-encryption-customer-algorithm
Use this header to specify the encryption algorithm. The header value must beAES256
.
x-amz-server-side-encryption-customer-key
Use this header to provide the 256-bit, base64-encoded encryption key for Amazon S3 to use to encrypt or decrypt your data.
x-amz-server-side-encryption-customer-key-MD5
Use this header to provide the base64-encoded 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a message integrity check to ensure that the encryption key was transmitted without error.https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html
So you can use the pre-signed URL from a server using an HTTP client library (by injecting these headers with the request) or you could use it from the browser from Javascript, similarly, or with tools like Postman and Curl, but you can't use it as a clickable or pastable hyperlink, because a URL doesn't provide a way to specify HTTP headers. And, of course, it seems like a bad idea to use it from browser-side JS, too, since that reveals the encryption key in clear text... so if you are planning to download an object stored with SSE-C, that's only appropriate in a secure environment, anyway, because of the need to handle the key in the clear.
Upvotes: 2