对接民生银行加/解密与加/验签

class TestBankAction extends Action
{
    //商户私钥
    protected $secretKey = ''; //放上即可

    //民生公钥
    protected $cmbcPubKey = ''; //放上即可

    //商户解密的密码
    protected $pwd = '123123'; //解密,签名

    //取文件参数
    protected $platformId = ''; //一级商户号
    protected $merchantNo = ''; //一级签约编码
    protected $fileType = 'PAYMENT'; //缴费方式 PAYMENT:已缴账单文件 充值账单文件:WITHHOLD
    protected $segmentIndex = '0'; //为0时获取块数
    protected $segmentSize = '1'; //分块文件大小 单位:KB
    protected $reserve = '没有备注'; //备注信息
    protected $url = 'https://wxpay.cmbc.com.cn/mobilePlatform/fileDownload.do';

    public function index()
    {
        echo 123;die;
        $data = file_get_contents("php://input");
        $res = file_put_contents('Lib/Action/log/a.txt', $data);
        if (!$res) {
            echo 'FAIL';
            die;
        }
        echo $this->encrypt($data);
    }

    /**
     * @param string base64 $data ; $flag 是否返回解密后的信息
     * @return success || ''
     * 解密
     */

    protected function encrypt($data,$flag = '')
    {
        require_once("Lib/Action/cmbc/php_java.php");//引用LAJP提供的PHP脚本
        try {
            $json_data = json_decode($data, true);
            $base64EnvelopeData = $json_data['context'];

            if ($flag) {
                $base64EnvelopeData = $data;
            }

            //签名算法
            $signAlg = 'SM4/CBC/PKCS7Padding';
            $base64P12Data = $this->secretKey;
            $p12Password = $this->pwd;
            $ret = lajp_call("cfca.sadk.api.EnvelopeKit::openEvelopedMessage", $base64EnvelopeData, $signAlg, $base64P12Data, $p12Password);
            file_put_contents('Lib/Action/log/b.txt', $ret,FILE_APPEND); //返回数据写入文件
            $return_data = json_decode($ret, true);
            //当确实解密成功后再返回success
            if ($return_data['Code'] == '90000000' && $return_data['Base64SourceString']) {

                if ($flag) {
                    $back = $this->checkSign($return_data['Base64SourceString'],true);
                    //验签成功后返回解密后的数据
                    if ($back) {
                        return $return_data['Base64SourceString'];
                    }
                }
                $back = $this->checkSign($return_data['Base64SourceString']);
                if ($back) {
                    return 'SUCCESS';
                }
            } else {
                file_put_contents('Lib/Action/log/encrypt_err.txt', $ret.'解密失败',FILE_APPEND);
            }
        } catch (Exception $e) {
            file_put_contents('Lib/Action/log/err.txt', $e->getMessage(),FILE_APPEND);
        }
    }


    /**
     * @param base64 string $baseSource
     * @return mixd
     * 验签
     */
    protected function checkSign($baseSource,$flag = '')
    {
        require_once("Lib/Action/cmbc/php_java.php");//引用LAJP提供的PHP脚本
        $decode_data = base64_decode($baseSource);
        $arr_data = json_decode($decode_data, true);
        $sign = $arr_data['sign']; //string
        $source_data = base64_encode($arr_data['body']); //json
        try {
            $signAlg = 'SM3withSM2';
            $base64SourceData = $source_data;
            $base64X509CertData = $this->cmbcPubKey;
            $base64P1SignatureData = $sign;
            $ret = lajp_call("cfca.sadk.api.SignatureKit::P1VerifyMessage", $signAlg,$base64SourceData, $base64X509CertData,$base64P1SignatureData);
            file_put_contents('Lib/Action/log/sign.txt', $ret);
            $res = json_decode($ret,true);
            if ($res['Code'] == '90000000' && $res['Result'] == 'True') {
                if ($flag) {
                    return true;
                }
                $result = $this->addData($arr_data['body']);
                if ($result) {
                    return true;
                }
            }
            file_put_contents('Lib/Action/log/sign_r.txt', $ret.'验签失败',FILE_APPEND);
            return false;
        } catch (Exception $e) {
            file_put_contents('Lib/Action/log/sign_err.txt', $ret,FILE_APPEND);
        }
    }

    /**
     * @param array $arr_data
     * @return bool
     * 写入数据库
     */

    protected function addData($arr_data)
    {
      $model = M('cmbc_data');
      $arr_data = json_decode($arr_data,true);
      $post['paymentmode'] = trim($arr_data['paymentMode']);
      $post['billtype'] = trim($arr_data['billType']);
      $post['feeproject'] = trim($arr_data['feeProject']);
      $post['tranamount'] = trim($arr_data['tranAmount']);
      $post['clientname'] = trim($arr_data['clientName']);
      $post['merid'] = trim($arr_data['merId']);
      $post['paynumber'] = trim($arr_data['payNumber']);
      $post['paynumbertype'] = trim($arr_data['payNumberType']);
      $post['remark1'] = trim($arr_data['remark1']);
      $post['remark2'] = trim($arr_data['remark2']);
      $post['remark3'] = trim($arr_data['remark3']);
      $post['feetype'] = trim($arr_data['FeeType']);
      $post['payorderno'] = trim($arr_data['payOrderNo']);
      file_put_contents('Lib/Action/log/post.txt', $post);
      $res = $model->add($post);
      if ($res) {
          file_put_contents('Lib/Action/log/add.txt', $res);
          return true;
      }
        file_put_contents('Lib/Action/log/add_err.txt', $res,FILE_APPEND);
    }


    /**
     * 下载前一天缴费数据文件
     */

    public function getTxt()
    {
        $total_count = $this->getCount(); //文件块数量
        if ($total_count >= 1) {
            for ($i=1;$i<=$total_count;$i++) {
                $txt_data = $this->getCount($i,true);
                header ( "Content-type:text/plain" );
                header ( "Content-Disposition:filename=" . iconv ( "UTF-8", "gbk//IGNORE", "缴费数据导出" ) . ".txt" );

                // 打开PHP文件句柄,php://output 表示直接输出到浏览器
                $fp = fopen('php://output', 'a');
                fwrite($fp,$txt_data);
                fclose($fp);
            }
        }
    }


    /**
     * 获取块文件个数
     * @param mark 获取数据或获取块数
     */
    public function getCount($num = 0,$mark = '')
    {
        $date = date('Ymd',strtotime('-2 day')); //格式 20180523
        $json = '{"platformId":"'.$this->platformId.'","slcTransDate":"'.$date.'","segmentIndex":"'.$num.'","fileType":"'.$this->fileType.'","merchantNo":"'.$this->merchantNo.'","segmentSize":"'.$this->segmentSize.'","reserve":"'.$this->reserve.'"}';
        $json_base64 = base64_encode($json);
        $sign = $this->makeSign($json_base64); //获取签名
        //拼接签名信息
        $ori_sign = '{"sign":"'.$sign.'","body":"'.addslashes($json).'"}';
        $base64_ori = base64_encode($ori_sign);
        //获取加密信息
        $secret = $this->getEncrypt($base64_ori);
        //拼接请求报文
        $request_data ='{"businessContext":"'.$secret.'","merchantNo":"","merchantSeq":"","reserve1":"","reserve2":"","reserve3":"","reserve4":"","reserve5":"","reserveJson":"","securityType":"","sessionId":"","source":"","transCode":"","transDate":"","transTime":"","version":""}';
        $encrypt_data = $this->sendCurl($request_data);
        //解密响应报文
        $unencry_data =  $this->encrypt($encrypt_data,1); //返回解密后的base64格式报文
        $res_data = base64_decode($unencry_data);
        $res = json_decode($res_data,true);
        $body_data = json_decode($res['body'],true);

        if ($mark) { //获取文件内容
            return base64_decode($body_data['segmentContent']);
        }
        return $body_data['segmentCount']; //返回需要获取的文件块数
    }


    //获得签名
    protected function makeSign($json_base64)
    {
        require_once("Lib/Action/cmbc/php_java.php");//引用LAJP提供的PHP脚本
        try {
            $signAlg = 'SM3withSM2';
            $base64SourceData = $json_base64;
            $base64P12Data = $this->secretKey;
            $p12Password = $this->pwd;
            $ret = lajp_call("cfca.sadk.api.SignatureKit::P1SignMessage",$signAlg,$base64SourceData,$base64P12Data,$p12Password);
            $res = json_decode($ret,true);
            if ($res['Code'] == '90000000' && $res['Base64SignatureData']) {
                return $res['Base64SignatureData'];
            } else {
                file_put_contents('Lib/Action/log/makesign.txt', $ret,FILE_APPEND);
                return false;
            }
        } catch (Exception $e) {
            file_put_contents('Lib/Action/log/makesign_err.txt', $e,FILE_APPEND);
        }
    }

    //加密信息

    protected function getEncrypt($base64_ori)
    {
        require_once("Lib/Action/cmbc/php_java.php");//引用LAJP提供的PHP脚本
        try {
            $signAlg = 'SM4/CBC/PKCS7Padding'; //签名算法
            $base64SourceData = $base64_ori;
            $base64CertData = $this->cmbcPubKey; //民生公钥用来加密
            $ret = lajp_call("cfca.sadk.api.EnvelopeKit::envelopeMessage",$base64SourceData,$signAlg, $base64CertData);
            $res = json_decode($ret,true);
            if ($res['Code'] == '90000000' && $res['Base64EnvelopeMessage']) {
                return $res['Base64EnvelopeMessage'];
            } else {
                file_put_contents('Lib/Action/log/makeenv.txt', $ret,FILE_APPEND);
                return false;
            }
        } catch (Exception $e) {
            file_put_contents('Lib/Action/log/makeenv_err.txt', $e,FILE_APPEND);
        }
    }

    //发送报文请求
    protected function sendCurl($request_data)
    {
        $url = $this->url;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request_data);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($request_data)));
        $result = curl_exec($ch);
        $res = json_decode($result,true);
        if ($res['gateReturnType'] == 'S' && $res['businessContext']) {
            return $res['businessContext'];
        }
    }
}

猜你喜欢

转载自blog.csdn.net/youcijibi/article/details/80600283