如何解决 Amazon S3 预签名 URL 的 SigV4 签名不匹配错误?

1 分钟阅读
0

我在使用 Amazon Simple Storage Service(Amazon S3)预签名 URL 向我的 Amazon S3 桶发出请求时出现 SignatureDoesNotMatch 错误。

简短描述

当根据您向 AWS 发出的 HTTP 请求计算出的签名值与 Amazon S3 计算的值不匹配时,就会出现此错误。有关详细信息,请参阅错误代码列表

当您生成预签名 URL 时,为了对请求进行身份验证,客户端会为请求计算一个唯一签名。然后,Amazon S3 根据 HTTP 请求中发送的参数计算签名并比较两个签名。如果签名不匹配,您就会收到 SignatureDoesNotMatch 错误。

要排查此错误,请执行以下操作:

  • 验证 HTTP 方法: 确认您向 S3 发出的 GET、PUT 和 DELETE 等 HTTP 请求方法与生成请求的 HTTP 方法相匹配。
  • 检查秘密访问密钥: 确保使用正确的秘密访问密钥来生成预签名 URL。如果秘密访问密钥已修改或不正确,请使用正确的访问密钥重新生成预签名 URL。
  • 检查 URL 中的桶名称和密钥名称: 确保桶名称和对象密钥名称正确无误,并与您尝试访问的对象的名称相匹配。
  • 检查 HTTP 请求中使用的标头: 验证标头是否根据签名计算而来。确保用于生成签名的 HTTP 标头与 HTTP 请求中发送到 S3 的 HTTP 标头相匹配。
  • 确保 AWS 区域正确: 验证签名是否是为桶当前所在的区域生成。

解决方法

HTTP 方法不正确

生成预签名 URL 时,您会为该 URL 指定 HTTP 操作。当客户端在 HTTP 请求中发送的操作与 URL 中使用的 HTTP 操作不匹配时,就会出现此错误。例如,如果请求签名是针对 GET 的,但请求中使用的 HTTP 操作是 PUT,就会出现该错误。要使 URL 能够正常访问,请验证您是否是针对预期的 HTTP 方法生成并使用 URL。

秘密访问密钥不正确

当用于生成预签名 URL 的访问密钥或秘密访问密钥处于以下状态之一时,就会出现此错误:

  • 不正确
  • 无效
  • 已禁用

检查您没有向访问密钥添加任何不匹配的字符或不正确的空格。

确保您在签名生成期间提供的访问密钥和秘密密钥与 AWS 提供的访问密钥和秘密密钥相匹配。

密钥名称或桶名称不正确

当您使用为某个桶或密钥生成的预签名 URL 访问其他桶或密钥时,就会出现此错误。

验证桶名称和对象名称是否正确,并与 URL 签名生成时包含的名称和对象名称相匹配。请注意,大小写不匹配也会导致签名不匹配。

标头未签名或标头值不正确

确保您没有传递在预签名 URL 签名生成时未签名的标头。如果您打算使用预签名 S3 URL 发送标头,则在 URL 签名生成时必须考虑到这些标头。

此外,请确保您传递的标头的值与签名计算期间生成的值相匹配。标头值的任何不匹配,包括大小写不匹配,都会导致 SignatureDoesNotMatch 错误。

签名区域和桶所在区域不匹配

在将预签名 URL 发送到 S3 之前,请验证生成 URL 的区域是否与桶当前所在的区域是否相匹配。

使用 GetBucketLocation API 请求检查 S3 桶所在区域。您也可以运行以下 AWS 命令行界面(AWS CLI)命令:

$ aws s3api get-bucket-location --bucket example-bucket

**注意:**如果在运行 AWS CLI 命令时收到错误,请确保您使用的是最新版本的 AWS CLI

输出类似于以下内容:

{  
    "LocationConstraint": "us-west-2"  
}

相关信息

使用预签名 URL

当我尝试访问 S3 对象时,出现“请求已过期”错误。 为什么?

AWS 官方
AWS 官方已更新 1 年前