阿里云 云数据库 RDS 版 公共请求参数 签名结果串 Signature PHP生成方法,亲测实例可用 PHP签名生成

版权声明:本文为博主原创文章,转载请标注出处,谢谢。 https://blog.csdn.net/qq_33182756/article/details/82593785

首先看下阿里的签名机制:签名机制,好吧,太多太乱的。不过慢慢看,还是能看懂。

PHP,编写的代码:

function getSignature($data = [])
{
    $key = env('AKI', '');//这里是阿里云的accesskeyid 和accesskeysecret
    $secret = env('AKS', '');
//这是请求api 的公共请求参数,
    $publicParams = array(
        "Format" => "JSON",
        "Version" => "2014-08-15",
        "AccessKeyId" => $key,
        "Timestamp" => date('Y-m-d\TH:i:s\Z', time() - date('Z')),
//            date("Y-m-d\TH:i:s\Z"),
        "SignatureMethod" => "HMAC-SHA1",
        "SignatureVersion" => "1.0",
        "SignatureNonce" => substr(md5(rand(1, 99999999)), rand(1, 9), 14),
    );
    $params = array_merge($publicParams, $data);
    $params['Signature'] =  sign($params, $secret);
    $uri = http_build_query($params);
    $url = 'https://rds.aliyuncs.com/?'.$uri;
    return $url;
}

function sign($params, $accessSecret, $method = "GET")
{
    ksort($params);
    $stringToSign = strtoupper($method) . '&' . percentEncode('/') . '&';
    $tmp = "";
    foreach ($params as $key => $val) {
        $tmp .= '&' . percentEncode($key) . '=' . percentEncode($val);
    }
    $tmp = trim($tmp, '&');
    $stringToSign = $stringToSign . percentEncode($tmp);
    $key = $accessSecret . '&';
    $hmac = hash_hmac("sha1", $stringToSign, $key, true);
    return base64_encode($hmac);
}


function percentEncode($value = null)
{
    $en = urlencode($value);
    $en = str_replace("+", "%20", $en);
    $en = str_replace("*", "%2A", $en);
    $en = str_replace("%7E", "~", $en);
    return $en;
}

其中:

1、
date('Y-m-d\TH:i:s\Z', time() - date('Z'))  这表示:请求的时间戳。日期格式按照ISO8601标准表示,并需要使用UTC时间,格式为YYYY-MM-DDThh:mm:ssZ。例如,2013-08-15T12:00:00Z为北京时间2013年8月15日20点0分0秒。

date('Z')  : date('Z')返回时区相差的秒数

2、

substr(md5(rand(1, 99999999)), rand(1, 9), 14)   唯一随机数,用于防止网络重放攻击。在不同请求间要使用不同的随机数值。md5返回32字符,md5(,true)时,放回16位字符。substr 截取字符串

下面的sign 方法才是核心灵魂、

function sign($params, $accessSecret, $method = "GET")
{
    ksort($params);
    $stringToSign = strtoupper($method) . '&' . percentEncode('/') . '&';
    $tmp = "";
  1. 对编码后的参数名称和值使用英文等号(=)进行连接。
  2. 再把英文等号连接得到的字符串按参数名称的字典顺序依次使用&符号连接,即得到规范化请求字符串。下面的foreach就是执行这个
    foreach ($params as $key => $val) {
        $tmp .= '&' . percentEncode($key) . '=' . percentEncode($val);
    }
使用上一步构造的规范化字符串按照下面的规则构造用于计算签名的字符串,下面就是规范化

    $tmp = trim($tmp, '&');
    $stringToSign = $stringToSign . percentEncode($tmp);
按照RFC2104的定义,使用上面的用于签名的字符串计算签名HMAC值。
  注意
计算签名时使用的Key就是用户持有的Access Key Secret并加上一个“&”字符(ASCII:38),使用的哈希算法是SHA1。
    $key = $accessSecret . '&';
    $hmac = hash_hmac("sha1", $stringToSign, $key, true);//hash_hmac — 使用 HMAC 方法生成带有密钥的哈希值

按照Base64编码规则把上面的HMAC值编码成字符串,即得到签名值(Signature)。

    return base64_encode($hmac);//base64_encode — 使用 MIME base64 对数据进行编码
}
  1. 对每个请求参数的名称和值进行编码。名称和值要使用UTF-8字符集进行URL编码,URL编码的编码规则是:

    1. 对于字符 A-Z、a-z、0-9以及字符(-)、(_)、(.)、(~)不编码。
    2. 对于其他字符编码成“%XY”的格式,其中XY是字符对应ASCII码的16进制表示。比如英文的双引号(”)对应的编码就是%22。
    3. 对于扩展的UTF-8字符,编码成“%XY%ZA…”的格式。
    4. 需要说明的是英文空格( )要被编码是%20,而不是加号(+)。
      注意
      一般支持URL编码的库(比如Java中的java.net.URLEncoder)都是按照“application/x-www-form-urlencoded”的MIME类型的规则进行编码的。实现时可以直接使用这类方式进行编码,php 用urlencode() 进行编码,再把编码后的字符串中加号(+)替换成%20、星号(*)替换成%2A、%7E替换回波浪号(~),即可得到上述规则描述的编码字符
方法如下:
function percentEncode($value = null)
{
    $en = urlencode($value);
    $en = str_replace("+", "%20", $en);  加号(+)替换成%20
    $en = str_replace("*", "%2A", $en);  * 号替换成%2A
    $en = str_replace("%7E", "~", $en);   %7E 替换成(~)
    return $en;
}

如果你有什么问题,欢迎留言。。 

猜你喜欢

转载自blog.csdn.net/qq_33182756/article/details/82593785
今日推荐