我使用服务器端加密和客户提供的密钥(SSE-C)上传了加密对象。是否可以使用AWS S3中的预签名URL下载对象?
我尝试过这样
GeneratePresignedUrlRequest generatePresignedUrlRequest1 = new GeneratePresignedUrlRequest("bucketname", "objectpath")
.withMethod(HttpMethod.GET)
.withSSECustomerKey(new SSECustomerKey("base64mykey"))
.withExpiration(new Date( System.currentTimeMillis() + (60 * 60 * 1000)));
链接已生成,但是在浏览器中访问该链接时出现此错误The request signature we calculated does not match the signature you provided. Check your key and signing method.
,对此有解决方案吗?
带有预签名URL的SSE-C可能无法按您期望的方式工作。
请求签名算法的输入包括所有以x-amz-*
开头的标头。这很重要,原因很快就会变得更加清楚。
签名生成代码需要在实际发出请求时知道这些值将是什么,这就是唯一的事情 .withSSECustomerKey()
所做的-提供签名算法需要的信息签名与您最终发送的实际请求匹配。
加密密钥实际上未嵌入在预签名的URL中。当实际发出请求时,需要再次提供它。
当使用服务器端加密和客户提供的加密密钥(SSE-C)时,必须使用以下请求标头提供加密密钥信息。
x-amz-server-side-encryption-customer-algorithm
使用此标头指定加密算法。标头值必须为AES256
。[
x-amz-server-side-encryption-customer-key
使用此标头为Amazon S3提供256位base64编码的加密密钥,以用于加密或解密您的数据。
x-amz-server-side-encryption-customer-key-MD5
使用此头提供根据RFC 1321提供的加密密钥的base64编码的128位MD5摘要。AmazonS3使用此头进行消息完整性检查,以确保传输的加密密钥没有错误。 >https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html
因此,您可以使用HTTP客户端库通过服务器使用预签名的URL(通过向请求注入这些标头),或者类似地,也可以通过Javascript从浏览器中使用它,或者使用Postman和Curl之类的工具,但是您不能将其用作可点击或可粘贴的超链接,因为URL不能提供指定HTTP标头的方法。而且,当然,从浏览器端的JS使用它似乎也是一个坏主意,因为这会以明文形式显示加密密钥...因此,如果您打算下载存储在SSE-C中的对象,那就是无论如何,仅由于安全需要处理密钥,因此仅适用于安全环境。