在PHP中签名过程以访问API网关端点



我正在尝试创建授权签名以访问IAM安全API网关端点。

$alg = "SHA256";
$CanonicalRequest = "GETn/dev/petsnnhost:3r4fgts8e5.execute-api.ap-northeast-1.amazonaws.comnx-amz-date:".$dd."nnhost;x-amz-datene3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
$CR =  str_replace("n", "", $CanonicalRequest);
$CR = str_replace("r", "", $CR);
$CR = strtolower($CR);
$StringToSign  = "AWS4-HMAC-SHA256n".$dd."n".$date->format( 'Ymd' )."/ap-northeast-1/execute-api/aws4_requestn".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秘密访问密钥和签名方法。详细信息请参考服务文档此请求的规范字符串应该具有被'GET n n n /dev/宠物nhost: 3 r4fgts8e5.execute api.ap -东北- 1. amazonaws.com nx-amz-date: 20161002 t231640z n nhost; x-amz-date n nThe ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"字符串到签名应该有被 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"

解决方案

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( 'YmdTHisZ' );
        $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;
    }

相关内容

  • 没有找到相关文章

最新更新