You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

从浏览器传图至S3遇Authorization error:需用AWS4-HMAC-SHA256

解决S3浏览器直传的AWS4-HMAC-SHA256签名错误

这个错误的根源很明确:你的S3存储桶所在的AWS区域要求使用AWS Signature Version 4进行身份验证,但你当前采用的是旧版的Signature Version 2签名方式,所以被拒绝了。下面一步步帮你修正:

1. 更新Policy文档

首先要给Policy添加AWS4签名必需的条件字段,确保它符合v4签名的规则。更新后的Policy示例如下:

{
  "expiration": "2024-12-01T12:00:00.000Z",
  "conditions": [
    {"bucket": "<my_bucket>"},
    ["starts-with", "$key", "user/kpms/"],
    {"acl": "public-read"},
    {"success_action_redirect": "http://<my_bucket>.s3.amazonaws.com/successful_upload.html"},
    ["starts-with", "$Content-Type", "image/"],
    {"x-amz-meta-uuid": "14365123651274"},
    ["starts-with", "$x-amz-meta-tag", ""],
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
    ["starts-with", "$x-amz-credential", "<你的访问密钥ID>/"],
    ["starts-with", "$x-amz-date", "<YYYYMMDD>"]
  ]
}
  • <YYYYMMDD>替换成你生成签名当天的日期(比如20240520),后续步骤要保持日期一致;
  • <你的访问密钥ID>替换为你的AWS Access Key ID。

2. 生成符合AWS4标准的签名

你之前用的工具只能生成v2签名,需要按照AWS4的签名流程重新生成:

  1. 编码Policy:把更新后的Policy做UTF-8编码,再进行Base64编码(这一步和之前操作一致);
  2. 生成签名密钥
    用你的AWS秘密访问密钥,结合日期、桶所在区域、服务标识s3,通过HMAC-SHA256迭代生成:
    kDate = HMAC-SHA256("AWS4" + <你的秘密访问密钥>, "<YYYYMMDD>")
    kRegion = HMAC-SHA256(kDate, "<桶所在区域>")
    kService = HMAC-SHA256(kRegion, "s3")
    kSigning = HMAC-SHA256(kService, "aws4_request")
    
  3. 生成最终签名:用上面得到的kSigning密钥,对Base64编码后的Policy做HMAC-SHA256加密,再把加密结果Base64编码,就是符合要求的Signature。

3. 更新HTML表单

需要添加几个隐藏字段来支持v4签名,把下面的代码加入你的表单中:

<input type="hidden" name="x-amz-algorithm" value="AWS4-HMAC-SHA256">
<input type="hidden" name="x-amz-credential" value="<你的访问密钥ID>/<YYYYMMDD>/<桶所在区域>/s3/aws4_request">
<input type="hidden" name="x-amz-date" value="<YYYYMMDD>T000000Z">
  • <桶所在区域>替换为你的存储桶实际区域(比如us-west-2),必须和生成签名密钥时用的区域一致;
  • <YYYYMMDD>T000000Z是日期的ISO格式,和之前的<YYYYMMDD>对应,比如20240520T000000Z

额外注意事项

  • CORS配置:确保你的S3桶CORS规则允许表单所在域名的POST请求,生产环境建议限制具体域名,示例配置如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
      <CORSRule>
        <AllowedOrigin>https://你的域名.com</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
      </CORSRule>
    </CORSConfiguration>
    
  • 密钥安全:绝对不要在前端代码中暴露你的AWS秘密访问密钥!生产环境建议通过后端服务生成Policy和签名,前端只获取生成好的参数,避免密钥泄露。

内容的提问来源于stack exchange,提问作者Sujay DSa

火山引擎 最新活动