You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用aws-sdk-php生成S3预签名URL遇SignatureDoesNotMatch错误的解决方法

AWS S3预签名URL签名不匹配问题排查与解决

问题场景

生成AWS S3预签名URL用于浏览器下载文件时,持续收到SignatureDoesNotMatch错误,错误详情如下:

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<AWSAccessKeyId>xxxxxxxxxx</AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256 20230729T002138Z 20230729/us-west-1/s3/aws4_request faxxxxxxxxxxxeb2a</StringToSign>
<SignatureProvided>c6d5xxxxxxxxx3df9</SignatureProvided>
<StringToSignBytes>41 57 53 34 2d 35 65 62 32 61 66 35 66 66 30 64</StringToSignBytes>
<CanonicalRequest>GET //dummy.pdf X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&amp;X-Amz-Credential=AKIXX%2F729%2Fus-west-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20230729T002138Z&amp;X-Amz-Expires=1200&amp;X-Amz-SignedHeaders=host host:test-storage.s3.us-west-1.amazonaws.com host UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>47 45 54 55 4e 53 49 47 4e 53 49 47 4e 55 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes>
<RequestId>EMXXXXXX032</RequestId>
<HostId>FcXXXXXXXXo=</HostId>
</Error>

使用的PHP代码如下:

$client = new S3Client([
    'version'     => 'latest',
    'region'      => 'us-west-1',
    'credentials' => [
        'key'    => 'xxxxxxx',
        'secret' => 'xxxxxxx',

    ],
]);

$cmd = $client->getCommand('GetObject', [
    'Bucket' => 'test-storage',
    'Key'    => 'dummy.pdf',
]);

$tmp          = $client->createPresignedRequest($cmd, '+20 minutes');
$presignedUrl = (string) $tmp->getUri();

生成的预签名URL示例:

https://test-storage.s3.us-west-1.amazonaws.com/dummy.pdf?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&amp;X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=AKI0729%2Fus-west-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20230729T004906Z&amp;X-Amz-SignedHeaders=host&amp;X-Amz-Expires=1200&amp;X-Amz-Signature=11111111534793c314b

错误原因分析

从错误返回的CanonicalRequest可定位核心问题:

  1. 路径格式错误:请求路径为//dummy.pdf,正确格式应为/dummy.pdf,双斜杠会导致签名计算逻辑偏差。
  2. Credential参数截断:X-Amz-Credential中的日期部分仅为729,AWS签名要求日期为完整YYYYMMDD格式(如20230729),截断会直接导致签名验证失败。
  3. SignedHeaders格式混乱:CanonicalRequest中重复出现host字段,不符合AWS签名规范,破坏了签名计算的一致性。
  4. SDK版本兼容性:使用latest作为SDK版本可能引入未预期的逻辑异常,导致签名生成流程出错。

解决方法

  1. 指定明确的SDK稳定版本
    将S3Client配置中的version从latest替换为AWS S3的标准稳定版本2006-03-01,避免版本兼容问题:

    $client = new S3Client([
        'version'     => '2006-03-01',
        'region'      => 'us-west-1',
        'credentials' => [
            'key'    => 'your-access-key',
            'secret' => 'your-secret-key',
        ],
    ]);
    
  2. 验证AWS凭证有效性
    确认访问密钥(key和secret)无拼写错误、无多余空格,且该密钥拥有目标S3对象的s3:GetObject权限。

  3. 检查生成URL的参数格式
    生成预签名URL后,手动验证:

    • X-Amz-Credential中的日期为完整YYYYMMDD格式
    • 请求路径为单斜杠开头(如/dummy.pdf)
    • X-Amz-SignedHeaders仅包含必要字段(如host),无重复内容
  4. 清理环境缓存
    若使用环境变量或缓存存储凭证,清理缓存并确认环境变量中的凭证值正确。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:18:10