PHP的RSA签名和验签

发布时间:2020-10-29作者:小灵龙点击:88

 
       // 签名生成     
  
    public  function SHA256withRSA($datas){
        
        // $datas='{"merc_order":"234234","pay_price":"130","pay_date":"15685985","imei":"25252525","pay_type":"scan"}';//对方获取加油站单个站点数据
      
        $data=json_encode($datas);
        //可以百度在线生成rsa,也可以使用php生成
        $privateKeypath="E:/phpstudy/WWW/gtzyc_api/config/certs/posterminal/cert_private.pem";
        $privateKeyfile = file_get_contents($privateKeypath);

    
        $pKeyId = openssl_pkey_get_private($privateKeyfile); // 加载私匙;
        $digest=openssl_digest($data,'sha256');//生成摘要

        $signature='';
        openssl_sign($digest, $signature, $pKeyId,OPENSSL_ALGO_SHA256);  //签名
        openssl_free_key($pKeyId);  
        return base64_encode($signature);  
    }
     //验签//用对方公钥验签
    public function checkrsa($signstr){
        $jsontoarr=json_decode($signstr,true);
        $signature=$jsontoarr['hfsign'];
        array_pop($jsontoarr);
        $data=json_encode($jsontoarr,JSON_UNESCAPED_UNICODE);
        log::info('checkrsa()获取的待签名串转译之后: '.$data);

        
        // 接入方公钥
        $publickeyFile='E:/phpstudy/WWW/gtzyc_api/config/certs/posterminal/other_cert_public.key';
        //摘要及签名的算法
        $digestAlgo='sha256';

        $algo=OPENSSL_ALGO_SHA256;

        //加载公钥
        $publickey=openssl_pkey_get_public(file_get_contents($publickeyFile));
        //生成摘要
        $digest=openssl_digest($data,$digestAlgo);

        //验签
        $verify=openssl_verify($digest,base64_decode($signature),$publickey,$algo);
        return $verify;
       
    }
    //接收对方订单数据,接入方调用我们的接口
    public function getPosOrder(Request $req){
        $orderstr=$req->getContent();//获取对方数据
        $orderarr=json_decode($orderstr,true);  //json格式转成数组    

        //判断数组是否为空,如果为空就不是json格式,因为json_decode()只转译json格式
        if(is_null($orderarr)){
            return response()->json(['code'=>'1003','msg'=>'待签名串不是json格式']);             
        }
        //验证数据是否为授权方发送
        $rsares=$this->checkrsa($orderstr);
        if($rsares!=1){
            return response()->json(['code'=>'1001','msg'=>'验签失败','merc_order'=>$orderarr['merc_order']]);
        }
        //验证所有字段是否符合数据库约束
        // $datas='{"merc_order":"234234","pay_price":"130","pay_date":"15685985","imei":"25252525","pay_type":"scan"}';
        $data=['merc_order'=>$orderarr['merc_order'],'pay_price'=>$orderarr['pay_price'],'pay_date'=>$orderarr['pay_date'],'worker_id'=>$orderarr['imei'],'pay_type'=>$orderarr['pay_type']];
        $validate=Validator::make($data,[
            'merc_order'=>'required|min:3|max:32'
            ,'pay_price'=>'required|numeric'
            ,'pay_date'=>'required|numeric'
            ,'worker_id'=>'required'
            ,'pay_type'=>'required|numeric'
        ]);
        if($validate->fails()){
            return response()->json(['code'=>'1004','msg'=>$validate->errors()->first()]);
        }
       
        $data['confirm_date']=$orderarr['pay_date'];
        $data['pay_terminal']=4;
        $data['is_type']=3;//1产品2积分3加油4洗车
        $data['order_state']=2;//订单状态 0:待付款 1:已付款,2已完成
        $data['info']='一卡通pos机支付全部加油订单金额';

        $orderid=DB::table('gczyc_wxcx_order')->where('merc_order',$orderarr['merc_order'])->value('id');
        if($orderid){
            return response()->json(['code'=>'1005','msg'=>'订单编号重复']);           
        }
   
        $db=DB::table('gczyc_wxcx_order')->insert($data);
      
        if($db){
            $back=['code'=>'1000','msg'=>'SUCCESS','merc_order'=>$orderarr['merc_order']];
            $signature=$this->SHA256withRSA($back);//签名
            return response()->json(['code'=>'1000','msg'=>'SUCCESS','merc_order'=>$orderarr['merc_order'],'hfsign'=>$signature]);            

        }else{
            return response()->json(['code'=>'1002','msg'=>'保存失败']);
        }
    }
    //我方调用接入方的接口。推送数据给接入方,
    public function reqExceptionOrder(Request $req){
        $array=array("merc_order"=>$req->merc_order,"is_normal"=>"1","order_price"=>$req->order_price,"kou_price"=>$req->pay_price,"back_price"=>$req->back_price);

        //签名
        $sign=$this->SHA256withRSA($array);
        $array['hfsign']=$sign;
        $data  = json_encode($array,JSON_UNESCAPED_UNICODE);  
        $headerArray =array("Content-type:application/json","Accept:application/json");       
      
        $url=‘/admin/pos/senddata’;
       
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);

        log::info('调用商户退款接口::::'.PHP_EOL.date('Y-m-d H:i:s').PHP_EOL.'发送'.PHP_EOL.var_export($data, true));

        $err = curl_error($curl);
        if ($err) {
            log::info('请求商户异常接口 cURL Error #:'. $err);
            return response()->json(['result'=>200,'msg'=>$err]);

        }
        if(empty($output)){
            log::info('请求商户异常接口,返回的$output为空,可能银行系统出错');
            return response()->json(['result'=>200,'msg'=>'返回数据为空']);
        }
        curl_close($curl);

        $res=json_decode($output,true);
        if($res['code']==1){
              log::info('请求商户完成接口,返回的为1');
              // 验签
            $verify=$this->checkrsa($output,$mercfile);
            if($verify==1){
                return response()->json(['result'=>100,'msg'=>$res['msg']]);
            }else{
                log::info('请求商户异常订单接口完成,但是验签失败。。。');
                return response()->json(['result'=>200,'msg'=>'验签失败']);
            }
        }else{
            log::info('请求商户异常订单接口完成,但是返还结果处理失败。。。'.$res['msg']);
            return response()->json(['result'=>200,'msg'=>$res['msg']]);
        }
       
    }

标签:php,sha256withrs