如何修复'我们计算的请求签名与签名'错误不匹配?

Jos*_*Lam 53 amazon-s3 amazon-web-services aws-php-sdk

我已经在网上搜索了两天以上,可能已经浏览了大多数在线记录的场景和解决方法,但到目前为止我没有任何作用.

我在运行PHP 5.3的AWS SDK for PHP V2.8.7上.我正在尝试使用以下代码连接到我的S3存储桶:

// Create a `Aws` object using a configuration file

        $aws = Aws::factory('config.php');

        // Get the client from the service locator by namespace
        $s3Client = $aws->get('s3');

        $bucket = "xxx";
        $keyname = "xxx";

        try {
            $result = $s3Client->putObject(array(
                'Bucket'        =>      $bucket,
                'Key'           =>      $keyname,
                'Body'          =>      'Hello World!'
            ));
            $file_error = false;
        } catch (Exception $e) {
            $file_error = true;
            echo $e->getMessage();
            die();
        }
        //  
Run Code Online (Sandbox Code Playgroud)

我的config.php文件如下:

<?php

return array(
    // Bootstrap the configuration file with AWS specific features
    'includes' => array('_aws'),
    'services' => array(
        // All AWS clients extend from 'default_settings'. Here we are
        // overriding 'default_settings' with our default credentials and
        // providing a default region setting.
        'default_settings' => array(
            'params' => array(
                'credentials' => array(
                    'key'    => 'key',
                    'secret' => 'secret'
                )
            )
        )
    )
);
Run Code Online (Sandbox Code Playgroud)

它产生以下错误:

我们计算的请求签名与您提供的签名不匹配.检查您的密钥和签名方法.

我已经检查了我的访问密钥和秘密至少20次,生成了新的密钥,使用不同的方法传递信息(即配置文件并在代码中包含凭据),但目前没有任何工作.

Jos*_*Lam 49

经过两天的调试,我终于发现了问题......

我分配给对象的键以句点开始,即..\images\ABC.jpg,这导致错误发生.

我希望API提供更有意义和相关的错误信息,唉,我希望这会帮助其他人!

  • 除此之外,当我的密钥中有加号“+”时,我收到了此错误消息。 (8认同)
  • 对我来说,问题是键内的**空格** (6认同)
  • 斜线也对我造成了这个问题。您只需要path / to / file,而不是/ path / to / file (5认同)
  • 当我在上传文件请求中没有提供“Content-Type”标头时,我收到了此消息 (4认同)
  • 我必须将 URL 中的加号 (`+`) 替换为 `%20`。 (4认同)
  • 我几乎花了整个工作日才发现我的 kotlin 服务器正在设置“image/jpeg”的内容类型,而我的 javascript 库正在设置“image/jpg”的内容类型标头。那一个小电子...几乎整个工作日...我阅读了 min.io 文档,安装了 mc,做了 mc 管理跟踪等,盯着日志几个小时...一个电子... jpeg...# @#!IM$#@M! (3认同)
  • 就我而言,这是由存储桶参数中的路径引起的。我没有使用 `bucket = "bucketname"`,而是使用了 `bucket = "bucketname/something"`。这也会导致签名不匹配错误。 (2认同)
  • 我在 SERVER_SECRET_KEY 中间有一个 /,经过三个小时的研究后解决了...... (2认同)
  • 就我而言,我发出的是 POST 请求,而不是 PUT(“getSignedUrlPromise”方法有一个操作参数“putObject”) (2认同)
  • 来到这里,使用 Minio 遇到了这个问题。我可以确认:HTTP 动词不匹配将触发签名失败以及某处的附加字符。以此为例说明如何不创建 API 错误报告。 (2认同)

Ros*_*don 29

我刚刚遇到过这种情况,我有点不好意思地说,这是因为我使用的是 HTTP POST 请求而不是 PUT。

尽管我很尴尬,但我还是想分享一下,以防有人因此而苦恼一个小时。

  • 哈哈,我很高兴你分享了这个——我做了同样的事情,甚至没有想到要检查一下! (5认同)

Ale*_*ine 22

我用错误的凭据收到此错误.我认为当我最初粘贴它时会有隐形字符.

  • 我只是双击“key_hash_lala/key_hash_continues”,它只选择了一个部分。唉,告诉用户“密码错误,老兄!”有多难? (5认同)

Ole*_*leg 16

我在 nodejs 中遇到了同样的错误。但是添加signatureVersions3 构造函数帮助了我:

const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4',
});
Run Code Online (Sandbox Code Playgroud)

  • 在我偶然发现这个之前尝试了很多事情!这就是我的答案。 (2认同)
  • 这也为我解决了这个问题。 (2认同)

Har*_*jah 16

如果您的密钥之前或之后有空格,则似乎主要发生此错误


ecd*_*per 7

尝试复制具有某些UTF8字符的对象时,我遇到了同样的问题.下面是一个JS示例:

var s3 = new AWS.S3();

s3.copyObject({
    Bucket: 'somebucket',
    CopySource: 'path/to/Weird_file_name_ðO?pi?u.jpg',
    Key: 'destination/key.jpg',
    ACL: 'authenticated-read'
}, cb);
Run Code Online (Sandbox Code Playgroud)

通过编码CopySource解决 encodeURIComponent()


Seb*_*ian 7

另一个可能的问题可能是元值包含非 US-ASCII 字符。对我来说,在将值添加到 putRequest 时,它有助于对值进行 UrlEncode:

request.Metadata.Add(AmzMetaPrefix + "artist", HttpUtility.UrlEncode(song.Artist));
request.Metadata.Add(AmzMetaPrefix + "title", HttpUtility.UrlEncode(song.Title));
Run Code Online (Sandbox Code Playgroud)


sar*_*rir 6

实际上在 Java 中我遇到了同样的错误。花了 4 个小时调试它之后,我发现问题出在 S3 对象中的元数据中,因为在 s3 文件中放置缓存控件时有空间。这个空间在 1.6 中是允许的。*版本,但在 1.11.* 中是不允许的,因此会引发签名不匹配错误


sau*_*abh 6

如果上述其他解决方案都不适合您,请尝试使用

aws configure
Run Code Online (Sandbox Code Playgroud)

此命令(AWS CLI 入门)将打开一组选项,询问密钥、区域和输出格式。

希望这可以帮助!


Ali*_*liS 6

我的 AccessKey 有一些特殊字符没有正确转义。

我在复制/粘贴密钥时没有检查特殊字符。绊倒了我几分钟。

一个简单的反斜杠修复了它。示例(显然不是我真正的访问密钥):

secretAccessKey: 'Gk/JCK77STMU6VWGrVYa1rmZiq+Mn98OdpJRNV614tM'

变成

secretAccessKey: 'Gk\/JCK77STMU6VWGrVYa1rmZiq\+Mn98OdpJRNV614tM'


AVI*_*per 5

就我而言,我将 S3 url 解析为其组件。

例如:

Url:    s3://bucket-name/path/to/file
Run Code Online (Sandbox Code Playgroud)

被解析为:

Bucket: bucket-name
Path:   /path/to/file
Run Code Online (Sandbox Code Playgroud)

路径部分包含前导“/”导致请求失败。


Daw*_* K. 5

对我来说,我使用 axios 并且默认它发送标头

content-type: application/x-www-form-urlencoded
Run Code Online (Sandbox Code Playgroud)

所以我改为发送:

content-type: application/octet-stream
Run Code Online (Sandbox Code Playgroud)

并且还必须将此 Content-Type 添加到 AWS 签名

const params = {
    Bucket: bucket,
    Key: key,
    Expires: expires,
    ContentType = 'application/octet-stream'
}

const s3 = new AWS.S3()
s3.getSignedUrl('putObject', params)
Run Code Online (Sandbox Code Playgroud)


小智 5

在 aws-php-sdk 的先前版本中,在弃用该S3Client::factory()方法之前,您可以将文件路径的一部分(或KeyS3Client->putObject()parameters 中调用)放置在bucket 参数上。我在生产中使用了一个文件管理器,使用 v2 SDK。由于工厂方法仍然有效,我没有在更新到~3.70.0. 今天我花了两个小时的大部分时间来调试为什么我开始收到这个错误,它最终是由于我传递的参数(曾经有效):

$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures/catsinhats',
    'Key' => 'whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);
Run Code Online (Sandbox Code Playgroud)

我必须将catsinhats存储桶/密钥路径的一部分移动到Key参数,如下所示:

$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures',
    'Key' => 'catsinhats/whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);
Run Code Online (Sandbox Code Playgroud)

我相信正在发生的是该Bucket名称现在正在被 URL 编码。在进一步检查我从 SDK 收到的确切消息后,我发现了这一点:

执行PutObject时出错https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png

AWS HTTP 错误:客户端错误: PUT https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png导致403 Forbidden

这表明/I 提供给我的Bucket参数已经通过urlencode(),现在是%2F

签名的工作方式相当复杂,但问题归结为存储桶和密钥用于生成加密签名。如果它们在调用客户端和 AWS 内不完全匹配,则请求将被拒绝并返回 403。错误消息确实指出了问题:

我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。

所以,我Key错了,因为我Bucket错了。


小智 5

我遇到过同样的问题。我使用默认方法 PUT 设置来定义预签名 URL,但尝试执行 GET。该错误是由于方法不匹配造成的。


Elo*_*ito 5

在我的情况下,我s3.getSignedUrl('getObject')在需要使用时使用s3.getSignedUrl('putObject')(因为我使用 PUT 上传我的文件),这就是签名不匹配的原因。


小智 5

对于 Python 集 - signature_version s3v4

s3 = boto3.client(
   's3',
   aws_access_key_id='AKIAIO5FODNN7EXAMPLE',
   aws_secret_access_key='ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE',
   config=Config(signature_version='s3v4')
)
Run Code Online (Sandbox Code Playgroud)


小智 5

我遇到了同样的问题,我遇到的问题是我导入了错误的环境变量,这意味着我的 AWS 密钥错误。根据阅读所有答案,我会验证您的所有访问 ID 和密钥是否正确,并且没有其他字符或任何内容。


P S*_*tro 5

当我故意给出了错误的具有“秘密”价值的密钥时,它给出了这个错误。我期待一些有效的错误消息详细信息,例如“身份验证失败”或其他内容