版权声明:本文为博主原创文章,转载请标注出处,谢谢。 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 = "";
- 对编码后的参数名称和值使用英文等号(=)进行连接。
- 再把英文等号连接得到的字符串按参数名称的字典顺序依次使用&符号连接,即得到规范化请求字符串。下面的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 对数据进行编码
}
-
对每个请求参数的名称和值进行编码。名称和值要使用UTF-8字符集进行URL编码,URL编码的编码规则是:
- 对于字符 A-Z、a-z、0-9以及字符(-)、(_)、(.)、(~)不编码。
- 对于其他字符编码成“%XY”的格式,其中XY是字符对应ASCII码的16进制表示。比如英文的双引号(”)对应的编码就是%22。
- 对于扩展的UTF-8字符,编码成“%XY%ZA…”的格式。
- 需要说明的是英文空格( )要被编码是%20,而不是加号(+)。
方法如下:
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;
}
如果你有什么问题,欢迎留言。。