php - 签署我的请求时我做错了什么? AWS SignatureV4 和 PHP

标签 php amazon-web-services request signature

我已经被这个问题困了两天了。我编写了一个 Python 脚本,它向 AWS Pinpoint 服务发出 PUT 请求。
与许多其他 AWS 服务一样,Pinpoint 需要对请求进行签名验证,我设法在 Python 中处理了这一点。

现在我正在尝试将我的脚本翻译成 Symfony 的 PHP 服务。当我向 AWS pinpoint 运行我的第一个请求时,我得到以下信息:

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details. The Canonical String for this request should have been\n'PUT\n/v1/apps/.../endpoints/...\n\ncontent-type:application/json\nhost:pinpoint.eu-west-1.amazonaws.com\nx-amz-content-sha256:de98d86577f0e1...655e6de27154af1c05ab34\nx-amz-date:20191226T151542Z\nx-amz-security-token:IQoJb....\nx-amz-user-agent:aws-amplify/1.1.2 react-native aws-amplify/1.1.2 react-native callback\n\ncontent-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent\n0240a9479d0a66d74eaae42dc...95247aaa800fcbe5cf2

The String-to-Sign should have been 'AWS4-HMAC-SHA256\n20191226T151542Z\n20191226/eu-west-1/mobiletargeting/aws4_request\nb2c451534fe370503ecf4068b45c...63e91280cc3187ae3230034107



所以我已经检查过我的规范字符串是否错误,这与 AWS 要求的完全相同。 String-to-Sign 与 Canonical String 哈希不同。

这是我的标题功能
public function create_headers($data,\DateTime $time,$canonical_uri,$method,$to_api=null)
    {
        $amz_date = $time->format('Ymd\THis\Z');
        $date_stamp = $time->format('Ymd');
        $payload_hash = hash('sha256',$data);#utf8_encode($data));
        $canonical_querystring = "";
        $canonical_headers = 'content-type:' . $this->content_type . '\n' . 'host:' . $this->host . '\n' . 'x-amz-content-sha256:' . $payload_hash . '\n' . 'x-amz-date:' . $amz_date . '\n' . 'x-amz-security-token:' . $this->security_token . '\n' . 'x-amz-user-agent:aws-amplify/1.1.2 react-native aws-amplify/1.1.2 react-native callback' . '\n';
        $signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent';


        $canonical_request = $method . '\n' . $canonical_uri . '\n' . $canonical_querystring . '\n' . $canonical_headers . '\n' . $signed_headers . '\n' . $payload_hash;

        echo '<br><br>';
        print_r(str_replace('\n','<br>',$canonical_request));
        #var_dump($canonical_request);
        $algorithm = 'AWS4-HMAC-SHA256';
        $credential_scope = "{$date_stamp}/{$this->region}/{$this->service}/aws4_request";
            #$date_stamp . '/' . $this->region . '/' . $this->service . '/' . 'aws4_request';
        #$credential_scope = $this->createScope($date_stamp,$this->region,$this->service);
        echo '<br><br>';
        #$string_to_sign = $algorithm . '\n' .  $amz_date . '\n' .  $credential_scope . '\n' .  hash('sha256', utf8_encode($canonical_request));
        $hash = hash('sha256', $canonical_request);
        $string_to_sign = "AWS4-HMAC-SHA256\n{$amz_date}\n{$credential_scope}\n{$hash}";
        print_r(str_replace('\n','<br>',$string_to_sign));
        echo '<br><br>';



        $signing_key = $this->get_signature_key($this->secret_key,$date_stamp,$this->region,$this->service);
        $signature = hash_hmac('sha256',$string_to_sign,$signing_key);

        $authorization_header = $algorithm . ' ' . 'Credential=' . $this->access_key . '/' . $credential_scope . ', ' .  'SignedHeaders=' . $signed_headers . ', ' . 'Signature=' . $signature;

        $headers = array(
            'host'=> $this->host,
            'content-type'=> $this->content_type,
            'x-amz-user-agent'=> 'aws-amplify/1.1.2 react-native aws-amplify/1.1.2 react-native callback',
            'x-amz-content-sha256'=> $payload_hash,
            'x-amz-security-token'=> $this->security_token,
            'x-amz-date'=> $amz_date,
            'authorization'=> $authorization_header
        );
        $this->s->headers = $headers;
        return $headers;
    }

几天来我一直在寻找我的错误,但我想我需要一个有新眼光的人......

谢谢!

最佳答案

经过数小时的自我质疑,我终于找到了为什么会出现该错误的原因。

在 PHP 中 "\n"和 '\n' 没有相同的含义。

"\n"是真正的换行符 - 这就是 AWS 的要求 .
'\n' 是由\和 n 个字符组成的字符串。

不过,AWS API 仍然很糟糕。

关于php - 签署我的请求时我做错了什么? AWS SignatureV4 和 PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59490458/

相关文章:

PHP MySQL查询以检查记录是否存在

javascript - 每次我调用它的twig模板时执行javascript

amazon-web-services - df -h 中的文件系统和挂载点

node.js - NodeJS套接字挂起超时

java - 在 ajax 调用中通过 id 获取 session

php - 由于 undefined variable ,从数据库检索数据时出现问题

php pdo mysql 不会返回带引号的文本

amazon-web-services - Spring Cloud AWS。 SQS。如何配置 FIFO 队列

python-3.x - Lambda 支持的自定义资源

android httprequest java.net.UnknownHostException