Подпись Версия 4 Процесс подписания в PHP для доступа к конечной точке шлюза API

Я пытаюсь создать Авторизованную подпись для доступа к конечной точке шлюза защищенного API IAM.

$alg = "SHA256"; $CanonicalRequest = "GET\n/dev/pets\n\nhost:3r4fgts8e5.execute-api.ap-northeast-1.amazonaws.com\nx-amz-date:".$dd."\n\nhost;x-amz-date\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; $CR = str_replace("\n", "", $CanonicalRequest); $CR = str_replace("\r", "", $CR); $CR = strtolower($CR); $StringToSign = "AWS4-HMAC-SHA256\n".$dd."\n".$date->format( 'Ymd' )."/ap-northeast-1/execute-api/aws4_request\n".hash( $alg, $CR ).""; // 1) HMACs $kSecret = 'AWS4' . $secret_key; $kDate = hash_hmac( $alg, $date->format( 'Ymd' ), $kSecret, true ); $kRegion = hash_hmac( $alg, $region, $kDate, true ); $kService = hash_hmac( $alg, $service, $kRegion, true ); $kSigning = hash_hmac( $alg, 'aws4_request', $kService, true ); $signature = hash_hmac( $alg, $StringToSign, $kSigning ); $authorization = array( 'Credential=' . $access_key . '/' . implode( '/', $scope ), 'SignedHeaders=' . implode( ';', array_keys( $can_headers ) ), 'Signature=' . $signature, ); $authorization = $request['algorithm'] . ' ' . implode( ',', $authorization ); $request['Authorization'] = $authorization; 

Но я получаю: «Подписанная нами подпись запроса не соответствует предоставленной вами подписи»

«message»: «Подписанная нами сигнатура запроса не соответствует предоставленной вами подписи. Проверьте свой секретный ключ доступа AWS и метод подписи. Подробнее см. в документации по обслуживанию. \ n \ nКананическая строка для этого запроса должна была быть \ n ' GET \ п / DEV / домашние животные \ п \ nhost: 3r4fgts8e5.execute-api.ap-northeast-1.amazonaws.com \ пх-АМЗ-дата: 20161002T231640Z \ п \ nhost; х-АМЗ-дата \ ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' \ п \ nСтрих-к-знаку должно быть \ n'AWS4-HMAC-SHA256 \ n20161002T231640Z \ n20161002 / ap-northeast-1 / execute-api / aws4_request \ n0b8c12e0a5f21137c5739a9d26056dfb081218631a9adcf37db1d2e09a014c4e '\ n "

Строка «Строка-в-знак»

 "AWS4-HMAC-SHA256 20161002T231640Z 20161002/ap-northeast-1/execute-api/aws4_request fb4f7ebdcb405bceed598ecc097267b929eeb3f8f075b1b7a776f53c8c8c6168" 

который полностью отличается от ожидаемого в AWS AWS.

Вот решение

 private function signRequest(){ $method ='GET'; $uri = '/dev'; $json = file_get_contents('php://input'); $obj = json_decode($json); if(isset($obj->method)) { $m = explode("|", $obj->method); $method = $m[0]; $uri .= $m[1]; } $secretKey = $this->session->data['aws_secret']; $access_key = $this->session->data['aws_key']; $token = $this->session->data['aws_token']; $region = 'ap-southeast-1'; $service = 'execute-api'; $options = array(); $headers = array(); $host = "YOUR-API-HOST.execute-api.ap-southeast-1.amazonaws.com"; //Or you can define your host here.. I am using API gateway. $alg = 'sha256'; $date = new DateTime( 'UTC' ); $dd = $date->format( 'Ymd\THis\Z' ); $amzdate2 = new DateTime( 'UTC' ); $amzdate2 = $amzdate2->format( 'Ymd' ); $amzdate = $dd; $algorithm = 'AWS4-HMAC-SHA256'; $parameters = (array) $obj->data; if($obj->data == null || empty($obj->data)) { $obj->data = ""; }else{ $param = json_encode($obj->data); if($param == "{}") { $param = ""; } $requestPayload = strtolower($param); $hashedPayload = hash($alg, $requestPayload); $canonical_uri = $uri; $canonical_querystring = ''; $canonical_headers = "content-type:"."application/json"."\n"."host:".$host."\n"."x-amz-date:".$amzdate."\n"."x-amz-security-token:".$token."\n"; $signed_headers = 'content-type;host;x-amz-date;x-amz-security-token'; $canonical_request = "".$method."\n".$canonical_uri."\n".$canonical_querystring."\n".$canonical_headers."\n".$signed_headers."\n".$hashedPayload; $credential_scope = $amzdate2 . '/' . $region . '/' . $service . '/' . 'aws4_request'; $string_to_sign = "".$algorithm."\n".$amzdate ."\n".$credential_scope."\n".hash('sha256', $canonical_request).""; //string_to_sign is the answer..hash('sha256', $canonical_request)// $kSecret = 'AWS4' . $secretKey; $kDate = hash_hmac( $alg, $amzdate2, $kSecret, true ); $kRegion = hash_hmac( $alg, $region, $kDate, true ); $kService = hash_hmac( $alg, $service, $kRegion, true ); $kSigning = hash_hmac( $alg, 'aws4_request', $kService, true ); $signature = hash_hmac( $alg, $string_to_sign, $kSigning ); $authorization_header = $algorithm . ' ' . 'Credential=' . $access_key . '/' . $credential_scope . ', ' . 'SignedHeaders=' . $signed_headers . ', ' . 'Signature=' . $signature; $headers = [ 'content-type'=>'application/json', 'x-amz-security-token'=>$token, 'x-amz-date'=>$amzdate, 'Authorization'=>$authorization_header]; return $headers; }