我们的想法是为每个上传的文件生成一个随机密钥,将此密钥传递给S3以加密它并将密钥存储在数据库中。一旦用户想要访问该文件,就会从数据库中读取密钥并再次传递给S3。
第一部分有效。我的对象已成功上传和加密,但我在检索它们时遇到了问题。
检索设置了请求标头的文件:
在对资源执行GET请求时设置x-amz-server-side-encryption-customer-algorithm
等请求标头时,可以正常工作,并且我可以访问它。但由于我希望这些资源为src
到<img>-Tag
,我无法执行需要设置标头的GET请求。
因此,我想到了:
预签名网址:
要创建预先签名的URL,我构建了所需字符串的HMAC SHA1并将其用作签名。 S3接受计算的签名,但在请求预签名URL时出现以下错误:
使用客户提供的密钥指定服务器端加密的请求必须提供适当的密钥。
网址格式为:
https://s3-eu-west-1.amazonaws.com/bucket-id/resource-id?x-amz-server-side-encryption-customer-algorithm=AES256&AWSAccessKeyId=MyAccessKey&Expires=1429939889&Signature=GeneratedSignature
显示错误的原因似乎对我来说非常清楚。签名过程中没有使用加密密钥。因此,请求无法工作。因此,我将加密密钥添加为Base64,并将Md5表示添加为URL的参数。该URL现在具有以下格式:
https://s3-eu-west-1.amazonaws.com/bucket-id/resource-id?x-amz-server-side-encryption-customer-algorithm=AES256&AWSAccessKeyId=MyAccessKey&Expires=1429939889&Signature=GeneratedSignature&x-amz-server-side-encryption-customer-key=Base64_Key&x-amz-server-side-encryption-customer-key-MD5=Md5_Key
虽然现在存在密钥(imho),但我确实收到了相同的错误消息。
的问题 的
有谁知道我如何通过GET
请求访问我的加密文件,该请求不提供任何标题,例如x-amz-server-side-encryption-customer-algorithm
?
答案 0 :(得分:1)
对我来说似乎很直观,你所尝试的应该是有效的。
显然,当他们说&#34;标题&#34; ...
时您必须在客户端应用程序中提供所有加密标头。
......他们的确实际上意味着标题,并且当您作为查询字符串的一部分提供时,S3并不接受这些特定值,正如您所期望的那样,因为S3有时会有些灵活在这方面。
我已经对此进行了测试,这就是我得出的结论:这样做并不受支持。
查询字符串(和签名)中包含GET
的{{1}}请求以及x-amz-server-side-encryption-customer-algorithm=AES256
和X-Amz-Server-Side-Encryption-Customer-Key
标题确实有效正如预期的......我相信你已经发现......但是将密钥和密钥md5放在查询字符串中,无论是否包含在签名中都似乎是死路一条。
起初看起来有些奇怪,他们不会在查询字符串中允许这样做,因为那里还有很多其他的东西......但是如果你再次遇到麻烦那么又一次加密某些内容,在链接中显示加密密钥似乎没什么意义......更不用说密钥会在S3访问日志中被捕获,使得加密看起来几乎没有任何意义 - 也许那就是他们要求它实际上是在标题而不是查询字符串中发送的动机。
根据我在测试中发现的情况,我没有看到直接在超链接中使用加密对象和客户提供的密钥的方法。
当然,间接地,S3存储桶前面的反向代理可以为您进行转换,从查询字符串中取适当的值并将它们放入标题中,而不是......但它真的与让S3使用AWS管理的密钥处理静态加密相比,我不清楚使用客户提供的可下载对象加密密钥可以获得什么。无论如何,您都可以使用静态加密。