1. 程式人生 > >阿里雲 雲資料庫 RDS 版 公共請求引數 簽名結果串 Signature PHP生成方法,親測例項可用 PHP簽名生成

阿里雲 雲資料庫 RDS 版 公共請求引數 簽名結果串 Signature PHP生成方法,親測例項可用 PHP簽名生成

首先看下阿里的簽名機制:簽名機制,好吧,太多太亂的。不過慢慢看,還是能看懂。

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;
}

如果你有什麼問題,歡迎留言。。