签名算法sha256withrsa,RSA数字证书公钥私钥生成,base64转码和文件日志

RSA数字证书公钥密钥生成:

在Linux系统下运行以下命令生成:

如果提示输出密码,可以为空,直接回车

生成的公钥rsa_public_key.pem和密钥rsa_private_key.pem文件在根目录下

# openssl

# genrsa -out rsa_private_key.pem 2048 Generating RSA private key, 2048 bit long modulus

# pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

# rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

 签名算法sha256withrsa:

$string:需要加密的字符串
$binary_signature:加密后保存到该变量中
$this->privateKey:RSA的私钥。(使用file_get_contents()读取私钥文件获取);

openssl_sign($string, $binary_signature, $this->privateKey, OPENSSL_ALGO_SHA256);

实例:

签名算法使用sha256withrsa算法,我方和渠道伙伴需交换RSA数字证书公钥用于验证签名,签名时,使用RSA数字证书私钥对签名参数串进行签名,RSA密用2048位及以上的,将签名值使用BASE64转码后填充到报文的数字签名域(Signature)。验证签名时,使用对方颁发的RSA数字证书公钥进行验签

/**
     * 签名 + post请求
     * @param array $param 请求参数
     * @param string $method 第三方方法名
     * @param string $api_method 接口名
     * @param string $is_big 通道别名
     * @param int $phone 手机号码
     * @return mixed
     */
    public function sign_post($param, $method, $api_method, $is_big, $phone)
    {
        $param['reqTime'] = date('YmdHis');
        $param['partnerId'] = $this->partnerId;
        $this->log($param, $api_method, $is_big, '签名前数据:', $phone);

        $signature = $this->makeSign($param);
        $this->log($signature, $api_method, $is_big, '签名值:');

        $param['signature'] = $signature;

        $types = explode('_',$api_method);
        if($types[0] == 'sk'){
            $requestUrl = $this->edUrl . $method;
        }else{
            $requestUrl = $this->zdUrl . $method;
        }

        $this->log($requestUrl, $api_method, $is_big, '请求url:');
        $this->log($param, $api_method, $is_big, '请求报文:');
        $res = $this->curl($requestUrl, $param);
        $this->log($res, $api_method, $is_big, '响应报文:');

        return $res;
    }

    /**
     * 生成签名
     * @param $params     array 请求参数
     * @param $privateKey string 秘钥
     * @return $sign string 签名内容
     */
    public function makeSign($params)
    {
        //签名步骤一:按字典序排序参数,再把所有数组值以“&”字符连接起来
        ksort($params);
        $string = $this->toUrlParams($params);

        openssl_sign($string, $binary_signature, $this->privateKey, OPENSSL_ALGO_SHA256);
        $sign = base64_encode($binary_signature);

        return $sign;
    }

    /**
     * 格式化参数格式化成url参数
     * @param $params array
     */
    public function toUrlParams($params)
    {
        $buff = "";
        foreach ($params as $k => $v) {
            if ($v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");

        return $buff;
    }

    //接口post请求
    public function curl($url = '', $data = '')
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        if (!empty($data)) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); //超时时间30秒
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);

        return $output;
    }

    /**
     * 验签
     * @param $data  array 需要验签的数据
     */
    public function verifySign($data, $publicKey)
    {

        if (empty($data) || empty($data['signature'])) {
            return false;
        }

        $sign = $data['signature'];
        unset($data['signature']);

        ksort($data);
        $string = $this->ToUrlParams($data);

        $pubKey = "-----BEGIN PUBLIC KEY-----\n" .
            wordwrap($publicKey, 64, "\n", true) .
            "\n-----END PUBLIC KEY-----";


        $result = (bool)openssl_verify($string, base64_decode($sign), $pubKey, OPENSSL_ALGO_SHA256);

        return $result;
    }

    /**
     * 日志记录
     * @param $data /内容
     * @param $method /方法名
     * @param $phone /手机号
     * @param string $is_big /通道别名
     * @param string $title /标题
     */
    public function Log($data, $method, $is_big, $title, $phone = '')
    {
        $str = is_array($data) ? json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : $data;
        if (empty($phone)) {
            $content = '【' . date('Y-m-d H:i:s') . '】' . $title . $str . PHP_EOL;
        } else {
            $content = ' phone:' . $phone . '【' . date('Y-m-d H:i:s') . '】' . $title . $str . PHP_EOL;
        }
        $path = APPPATH . "../PAYLOG/$is_big/$method/";

        if (!is_dir($path)) { //判断目录是否存在 不存在就创建
            mkdir($path, 0777, true);
        }
        file_put_contents($path . date("Y-m-d") . '.txt', $content, FILE_APPEND);
        //换行分割
        file_put_contents($path . date("Y-m-d") . '.txt', '------------------------' . PHP_EOL, FILE_APPEND);
    }

 

你可能感兴趣的:(PHP)