实现接口访问的HMAC-SHA1签名算法

来源:互联网 发布:caffe 训练好的模型 编辑:程序博客网 时间:2024/05/29 16:16

    技术QQ交流群:294088839

 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、发送请求即可。


    }