Java 使用AWS S3'中的预签名url下载对象(文件);行不通

Java 使用AWS S3'中的预签名url下载对象(文件);行不通,java,amazon-web-services,amazon-s3,download,Java,Amazon Web Services,Amazon S3,Download,我使用服务器端加密和客户提供的密钥(SSE-C)上传了加密对象。 是否可以使用AWS S3中的预签名URL下载对象 我试过这样做 GeneratePresignedUrlRequest generatePresignedUrlRequest1 = new GeneratePresignedUrlRequest("bucketname", "objectpath") .withMethod(HttpMethod.GET) .withSSECustomerKey(new

我使用服务器端加密和客户提供的密钥(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)));

链接已生成,但在浏览器中访问时,我收到此错误
我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。
有解决方案吗?

带有预签名URL的SSE-C可能无法按您预期的方式工作

请求签名算法的输入包括以
x-amz-*
开头的所有头。这一点意义重大,原因将在一瞬间变得更加清楚

签名生成代码需要知道当您实际发出请求时这些值是什么,这是
.withSSECustomerKey()
所做的唯一事情--提供签名算法需要的信息,以便签名与您最终发送的实际请求相匹配

加密密钥实际上没有嵌入到预签名的URL中。当请求实际发出时,需要再次提供它

使用带有客户提供的加密密钥(SSE-C)的服务器端加密时,必须使用以下请求头提供加密密钥信息

x-amz-服务器端​-加密​-客户算法
使用此标题指定加密算法。标题值必须为AES256

x-amz-服务器端​-加密​-客户密钥
使用此标头为Amazon S3提供256位base64编码的加密密钥,用于加密或解密数据

x-amz-服务器端​-加密​-customer-key-MD5
根据RFC 1321,使用此标头提供加密密钥的base64编码128位MD5摘要。AmazonS3使用此报头进行消息完整性检查,以确保加密密钥传输无误


因此,您可以使用HTTP客户端库从服务器使用预签名URL(通过将这些头与请求一起注入),也可以从Javascript的浏览器使用它,类似地,也可以使用Postman和Curl等工具,但不能将其用作可点击或可复制的超链接,因为URL不提供指定HTTP头的方法。当然,从浏览器端JS使用它似乎也是一个坏主意,因为它以明文形式显示加密密钥。。。因此,如果您计划下载存储在SSE-C中的对象,无论如何,这只适用于安全环境,因为需要以清除方式处理密钥。

SSE-C与预签名URL可能无法按您预期的方式工作

请求签名算法的输入包括以
x-amz-*
开头的所有头。这一点意义重大,原因将在一瞬间变得更加清楚

签名生成代码需要知道当您实际发出请求时这些值是什么,这是
.withSSECustomerKey()
所做的唯一事情--提供签名算法需要的信息,以便签名与您最终发送的实际请求相匹配

加密密钥实际上没有嵌入到预签名的URL中。当请求实际发出时,需要再次提供它

使用带有客户提供的加密密钥(SSE-C)的服务器端加密时,必须使用以下请求头提供加密密钥信息

x-amz-服务器端​-加密​-客户算法
使用此标题指定加密算法。标题值必须为AES256

x-amz-服务器端​-加密​-客户密钥
使用此标头为Amazon S3提供256位base64编码的加密密钥,用于加密或解密数据

x-amz-服务器端​-加密​-customer-key-MD5
根据RFC 1321,使用此标头提供加密密钥的base64编码128位MD5摘要。AmazonS3使用此报头进行消息完整性检查,以确保加密密钥传输无误

因此,您可以使用HTTP客户端库从服务器使用预签名URL(通过将这些头与请求一起注入),也可以从Javascript的浏览器使用它,类似地,也可以使用Postman和Curl等工具,但不能将其用作可点击或可复制的超链接,因为URL不提供指定HTTP头的方法。当然,从浏览器端JS使用它似乎也是一个坏主意,因为它以明文形式显示加密密钥。。。因此,如果您计划下载存储在SSE-C中的对象,无论如何,这只适用于安全环境,因为需要在clear中处理密钥