實現介面訪問的HMAC-SHA1簽名演算法

Json______發表於2017-10-13

PHP交流群:294088839,

Python交流群:652376983

 public function index(){

        $url  = '';
        $method = "POST";
        $arr=C('yjs');
        //第三方Id
        $arr['X-User-Id']='1';
       //訪問url路徑字尾
        $arr['path']='';
        $url=$url.$arr['path'];
        //get傳輸方式
        $get_params=array();
        //post傳輸方式 如果是get就把值寫 再上一個陣列中 如果是Post就把值寫在下面的陣列中
        $post_params=array('third_id'=>$arr['X-User-Id']);
         $header=$this->buildHeaders(
             //第三方ID
             $arr['X-User-Id'],
             //公鑰
             $arr['X-Auth-Access-Key'],
            //私鑰
             $arr['SecretKey'],
            //每個API字尾
             $arr['path'],
           //一個空陣列
             $get_params,
           //第三方ID放在陣列中
             $post_params,
             //訪問介面的時間
             $arr['X-Auth-Timestamp'],
            //簽名所用演算法
             $arr['X-Auth-Signature-Method'],
           //請求中的隨機字串,安全
             $arr['X-Auth-Nonce']
             );


        foreach($header as $k=>$v) {
            $h[] = $k.":".$v;
        }
       //  echo  $url;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, 1);            // 傳送一個常規的Post請求
        curl_setopt($curl, CURLOPT_HTTPHEADER, $h);     //把header表頭資訊傳送過去
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);  // 獲取的資訊以檔案流的形式返回
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($post_params)); // Post提交的資料包
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);  // 對認證證照來源的檢查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);  // 從證照中檢查SSL加密演算法是否存在
        $response = curl_exec($curl);
     //  var_dump( $response );
        $this->http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $this->http_info = array();
        $this->http_info = array_merge($this->http_info, curl_getinfo($curl));
        $this->url = $url;
        curl_close($curl);
     //   echo $response;
        
    }


    //編寫headers表頭資訊
    protected function buildHeaders( $third_id='', $access_key, $secret_key, $path, $get_params=array(), $post_params=array(),$Timestamp,$SignatureMethod,$Nonce){
        $headers = array();
        $headers['X-Auth-Access-Key'] = $access_key;
        $headers['X-Auth-Timestamp'] = $Timestamp;
        $headers['X-Auth-Signature-Method'] = $SignatureMethod;
        $headers['X-Auth-Nonce'] = $Nonce;
        // trim 去除字串首尾處的空白字元(或者其他字元)
        $headers['X-Auth-Path-Info'] = trim($path, '/');
        if( $third_id ){
            $headers['X-User-Id'] = $third_id;
        }


         $all_params = $headers + $get_params + $post_params;


          $auth_sign = $this->buildSign($secret_key, $all_params);
          $headers['X-Auth-Sign'] = $auth_sign;
         // var_dump($headers);
          return $headers;
    }


    //表頭資訊sign引數簽名 實現介面訪問的HMAC-SHA1簽名演算法
    protected  function buildSign($secret_key, $params){
        // array_keys 返回陣列中所有的鍵名
        $keys = array_keys($params);


        // sort 對陣列排序
        sort($keys);


        $tmp_array = array();
        //把傳過來的陣列降序排列 然後重新賦值 變成一個索引陣列 鍵和值拼接起來
        foreach($keys as $k) {
            if ($k == "X-Auth-Path-Info") {
                // stripslashes 反引用一個引用字串
                $tmp_array[] = $k . '=' . stripslashes(json_encode($params[$k]));
            } else {
                // json_encode 對變數進行 JSON 編碼
                $tmp_array[] = $k . '=' . json_encode($params[$k]);
            }
        }


        // implode 將一個一維陣列的值轉化為字串
        $base_str = implode('&', $tmp_array);
        //把json中的引號全部替換成控值
        $base_str =str_replace('"','',$base_str);
        // base64_encode 使用 MIME base64 對資料進行編碼
        // hash_hmac 使用HMAC方法生成一個金鑰的雜湊值
        // 在php中hash_hmac函式就能將HMAC和一部分雜湊加密演算法相結合起來實現HMAC-SHA1  HMAC-SHA256 HMAC-MD5演算法
        // 第一個引數要使用的雜湊演算法名稱,可以是上述提到的md5,sha1等
        //第二個引數要進行雜湊運算的訊息,也就是需要加密的明文。
        //第三個引數使用HMAC生成資訊摘要是所使用的金鑰。
        //第四個引數該引數為可選引數,預設為false,如果設為true,則返回原始二進位制資料表示的資訊摘要,否則返回16進位制小寫字串格式表示的資訊
        $res = base64_encode(hash_hmac("sha1", $base_str, $secret_key, true));
      //  var_dump($res);
        return $res;


        //一般來講,目前最流行的介面簽名方式,是採用hash_hamc('sha1')方法;
       //   1、將 Accesskey(公鑰)和Secretkey(私鑰)簡稱ak,sk,告知客戶端(或介面呼叫者)
       //2、按照介面提供方的要求,提取出需要加密的訊息串。比如uri;
      //3、通過hash_hamc('sha1',uri,Secretkey);得到簽名;
      ///3'、一般而言介面提供方,都會要求對加密串進行base64urlencode,防止簽名串被特殊字元分割,導致驗證無法通過。
     ///4、將簽名注入http協議頭中;$headerArr[] = 'accessToken:'.$akey.":".$ret;
      //5、傳送請求即可。

 

    }

 

 

相關文章