网站首页php

openssl签名及验签

发布时间:2017-06-28 18:49:53编辑:slayer.hover阅读(3466)

    *测试用到的公私钥:
       客户端公钥文件:publicKeyFile.crt

    服务端公钥文件:serverPublicKeyFile.crt


    客户端私钥文件:privateKeyFile.p12

    客户端私钥密码:privateKeyPassword

    p12文件:含有私钥,同时可以有公钥,有口令保护。



    1. 签名类代码如下:

    class SignLib{
        private    $signString;
        private    $config=[
                        'privateKeyFilePath'   =>    './certs/privateKeyFile.p12',
                        'password'         =>    'privateKeyPassword',
                        'serverPublicKeyFilePath' =>'./certs/serverPublicKeyFile.crt',
        ];
        /**
           *签名方法
           *参数:$params是要进行签名的数组
           *返回:签名字符串
           **/
        public function sign($params)    
        {        
            ksort($params);        
            $data = implode($params, '');        
            $privateKeyString = file_get_contents($this->config['privateKeyFilePath']);
            openssl_pkcs12_read($privateKeyString, $myPrivateKey, $this->config['password']);        
            openssl_sign($data, $mySign, $myPrivateKey['pkey']);        
            return base64_encode($mySign);    
        }
        /**
           *签名验证
           *参数:$result是要进行验签的数组,其中包含$result['sign']签名字符串
           *返回:Bool值成功或否
           **/
        public function sign_verify($result)    
        {        
            $sign = base64_decode($result['sign']);        
            unset($result['sign']);        
            $this->paramsToString($result);        
            $publicKey = openssl_x509_read(file_get_contents($this->config['serverPublicKeyFilePath']));        
            return openssl_verify($this->signString, $sign, $publicKey);
         }
        // 递归按照字典顺序    
        public function paramsToString($params)    
        {        
            ksort($params);        
            foreach ($params as $key => $val) {            
                if (is_array($val)) {                
                    $params[$key] = $this->paramsToString($val);            
                } else {                
                    $this->signString .= $val;            
                }        
            }        
            return $params;    
        }
    }


    2. 客户端附加签名发送请求示例:

        $signEx    =    new SignLib;
        $params    =    ['method'=>'doSomething','param'=>'myParam'];
        $params['sign']    =    $signEx->sign($params);
        $acturl        =    "http://yourserverurl";
        $result    =    curl($acturl, $params);


    3. 客户端验证服务端返回的签名:

        $signEx    =    new SignLib;
        $out    =    $signEx->sign_verify($result); //$result数组包含有$result['sign']签名字符串
        var_dump($out);






评论