我们正在考虑使用carrierwave_direct将文件直接从用户的浏览器上传到s3。 carrierwave_direct生成的表单包括我们的aws_access_key和一个"签名",它由以下代码生成:
def signature
Base64.encode64(
OpenSSL::HMAC.digest(
OpenSSL::Digest.new('sha1'),
aws_secret_access_key, policy
)
).gsub("\n","")
end
policy
参数是一种方法,使用Time.now生成,因此可能使攻击者很难找出aws_secret_access_key
。但是,如果仅仅aws_access_key和此签名足以作为此s3用户进行身份验证(即使它是有时间限制的),为什么攻击者需要我们的aws_secret_access_key
?他们只是重新加载页面才能获得可以使用一段时间的签名吗?我在这里缺少什么?
我担心的原因是因为我们在应用程序的其他部分使用相同的凭据来执行我们绝对不希望任意用户能够执行的操作,并且模糊/ carrierwave似乎没有提供一种方法来为一个操作使用一组凭据,而在另一个地方提供另一种凭证。
答案 0 :(得分:3)
签名仅对具有执行签名通过签名生成的策略文档所允许的操作的权限的用户进行身份验证。更改策略中的单个字节,签名无效。 (您可以通过手动调整来证明这一点。)
AWS访问密钥旨在安全公开。 AWS秘密是您永远不应该公开的,并且签名不包含足够的信息来以任何实际的方式对您的秘密进行反向工程,而不是暴力......密钥空间被认为太大而不实用。< / p>
尽管如此,最好(一如既往,不是特别在这里)使用不同的密钥/秘密对,它只具有完成目的所需的最低权限,并定期轮换它们。