美文网首页
RSA接口加密实现方法

RSA接口加密实现方法

作者: liuboxx1 | 来源:发表于2017-08-29 18:22 被阅读104次

    搞了一天,搜了好多资料,终于把公司接口RSA加密完成了,下面写一下完成的过程以及碰到的坑。

     $config = array(
         "config" => "C:/wamp64/bin/php/php5.6.16/extras/ssl/openssl.cnf",
         "digest_alg" => "sha512",
         "private_key_bits" => 1024,
         "private_key_type" => OPENSSL_KEYTYPE_RSA,
     );
    // Create the private and public key
    $res = openssl_pkey_new($config);
    
    // Extract the private key from $res to $privKey
    openssl_pkey_export($res, $privKey, NULL, $config);
    echo "Private Key: ".$privKey. '<br />';
    // Extract the public key from $res to $pubKey
    $pubKey = openssl_pkey_get_details($res);
    $pubKey = $pubKey["key"];
    echo "Public Key: ".$pubKey. '<br />';
    $data = 'token=coucou&tel=17600104539&url=https://www.coucouchina.com/Api/Index/manage?id=2';
    echo "Data: ".$data. '<br />';
    // Encrypt the data to $encrypted using the public key
    openssl_public_encrypt($data, $encrypted, $pubKey);
    $encrypted = base64_encode($encrypted);
    echo "Encrypted: ".$encrypted. '<br />';
    // Decrypt the data using the private key and store the results in $decrypted
    $encrypted = base64_decode($encrypted);
    openssl_private_decrypt($encrypted, $decrypted, $privKey);
    
    echo "Decrypted: ".$decrypted. '<br />';
    
    image.png

    一:首先用上面的代码生成private key和public key
    坑①:$config数组里面的路径不要填错
    坑②:第15行的 $config 不要忘记填

    二:在项目里面建立 rsa_public_key.pem 和 rsa_private_key.pem两个文件,把上一步生成的private key 和 public key 填入对应的文件之中
    坑①:格式正确一定要,该换行换行,不然下面会死得很难看

    class RSA  {  
        private $pubKey = null;  
        private $priKey = null;  
      
        /** 
         * 构造函数 
         * 
         * @param string 公钥文件(验签和加密时传入) 
         * @param string 私钥文件(签名和解密时传入) 
         */  
        public function __construct($public_key_file = '', $private_key_file = '')  
        {  
            if ($public_key_file) {  
                $this->_getPublicKey($public_key_file);  
            }  
            if ($private_key_file) {  
                $this->_getPrivateKey($private_key_file);  
            }  
        }  
      
        // 私有方法  
        /** 
         * 自定义错误处理 
         */  
        private function _error($msg)  
        {  
            die('RSA Error:' . $msg); //TODO
        }  
      
        /** 
         * 检测填充类型 
         * 加密只支持PKCS1_PADDING 
         * 解密支持PKCS1_PADDING和NO_PADDING 
         * 
         * @param int 填充模式 
         * @param string 加密en/解密de 
         * @return bool 
         */  
        private function _checkPadding($padding, $type)  
        {  
            if ($type == 'en') {  
                switch ($padding) {  
                    case OPENSSL_PKCS1_PADDING:  
                        $ret = true;  
                        break;  
                    default:  
                        $ret = false;  
                }  
            } else {  
                switch ($padding) {  
                    case OPENSSL_PKCS1_PADDING:  
                    case OPENSSL_NO_PADDING:  
                        $ret = true;  
                        break;  
                    default:  
                        $ret = false;  
                }  
            }  
            return $ret;  
        }  
      
        private function _encode($data, $code)  
        {  
            switch (strtolower($code)) {  
                case 'base64':  
                    $data = base64_encode('' . $data);  
                    break;  
                case 'hex':  
                    $data = bin2hex($data);  
                    break;  
                case 'bin':  
                default:  
            }  
            return $data;  
        }  
      
        private function _decode($data, $code)  
        {  
            switch (strtolower($code)) {  
                case 'base64':  
                    $data = base64_decode($data);  
                    break;  
                case 'hex':  
                    $data = $this->_hex2bin($data);  
                    break;  
                case 'bin':  
                default:  
            }  
            return $data;  
        }  
      
        private function _getPublicKey($file)  
        {  
            $key_content = $this->_readFile($file);  
            if ($key_content) {  
                $this->pubKey = openssl_get_publickey($key_content);  
            }  
        }  
      
        private function _getPrivateKey($file)  
        {  
            $key_content = $this->_readFile($file);  
            if ($key_content) {  
                $this->priKey = openssl_get_privatekey($key_content);               //格式问题会导致返回数据为false
            } 
        }  
      
        private function _readFile($file)  
        {  
            $ret = false;  
            if (!file_exists($file)) {  
                $this->_error("The file {$file} is not exists");  
            } else {  
                $ret = file_get_contents($file);  
            }  
            return $ret;  
        }  
      
        private function _hex2bin($hex = false)  
        {  
            $ret = $hex !== false && preg_match('/^[0-9a-fA-F]+$/i', $hex) ? pack("H*", $hex) : false;  
            return $ret;  
        }  
      
        /** 
         * 生成签名 
         * 
         * @param string 签名材料 
         * @param string 签名编码(base64/hex/bin) 
         * @return 签名值 
         */  
        public function sign($data, $code = 'base64')  
        {  
            $ret = false;  
            if (openssl_sign($data, $ret, $this->priKey)) {  
                $ret = $this->_encode($ret, $code);  
            }  
            return $ret;  
        }  
      
        /** 
         * 验证签名 
         * 
         * @param string 签名材料 
         * @param string 签名值 
         * @param string 签名编码(base64/hex/bin) 
         * @return bool 
         */  
        public function verify($data, $sign, $code = 'base64')  
        {  
            $ret = false;  
            $sign = $this->_decode($sign, $code);  
            if ($sign !== false) {  
                switch (openssl_verify($data, $sign, $this->pubKey)) {  
                    case 1:  
                        $ret = true;  
                        break;  
                    case 0:  
                    case -1:  
                    default:  
                        $ret = false;  
                }  
            }  
            return $ret;  
        }  
      
        /** 
         * 加密 
         * 
         * @param string 明文 
         * @param string 密文编码(base64/hex/bin) 
         * @param int 填充方式(貌似php有bug,所以目前仅支持OPENSSL_PKCS1_PADDING) 
         * @return string 密文 
         */  
        public function encrypt($data, $code = 'base64', $padding = OPENSSL_PKCS1_PADDING)  
        {  
            $ret = false;  
            if (!$this->_checkPadding($padding, 'en')) $this->_error('padding error');  
            if (openssl_public_encrypt($data, $result, $this->pubKey, $padding)) {  
                $ret = $this->_encode($result, $code);  
            }  
            return $ret;  
        }  
      
        /** 
         * 解密 
         * 
         * @param string 密文 
         * @param string 密文编码(base64/hex/bin) 
         * @param int 填充方式(OPENSSL_PKCS1_PADDING / OPENSSL_NO_PADDING) 
         * @param bool 是否翻转明文(When passing Microsoft CryptoAPI-generated RSA cyphertext, revert the bytes in the block) 
         * @return string 明文 
         */  
        public function decrypt($data, $code = 'base64', $padding = OPENSSL_PKCS1_PADDING, $rev = false)  
        {  
            $ret = false;  
            $data = $this->_decode($data, $code);  
            if (!$this->_checkPadding($padding, 'de')) $this->_error('padding error');  
            if ($data !== false) {  
                if (openssl_private_decrypt($data, $result, $this->priKey, $padding)) {  
                    $ret = $rev ? rtrim(strrev($result), "\0") : '' . $result;  
                }  
            }  
            return $ret;  
        }  
    }  
    
    ![image.png](https://img.haomeiwen.com/i421014/53cf0fc3cc0692da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ![image.png](https://img.haomeiwen.com/i421014/ceee292f9b07eadb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ![image.png](https://img.haomeiwen.com/i421014/761740c02d2a831d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ![image.png](https://img.haomeiwen.com/i421014/72141a3bdae8fba2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ![image.png](https://img.haomeiwen.com/i421014/e931ab21165cab59.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    $pubfile = 'C:\wamp64\www\coucou\rsa_public_key.pem';  
    $prifile = 'C:\wamp64\www\coucou\rsa_private_key.pem';  
    $rsa = new RSA($pubfile, $prifile);  
    $rst = array(  
        'ret' => 200,  
        'code' => 1,  
        'data' => array(1, 2, 3, 4, 5, 6),  
        'msg' => "success",  
    );  
    $ex = json_encode($rst);  
    //加密  
    $ret_e = $rsa->encrypt($ex);  
    //解密  
    $ret_d = $rsa->decrypt($ret_e);  
    echo $ret_e;
    echo '<pre>';
    echo $ret_d;
      
    echo '<pre>';  
      
    $a = 'test';  
    //签名  
    $x = $rsa->sign($a);  
    //验证  
    $y = $rsa->verify($a, $x);  
    var_dump($x, $y);  
    exit;  
    
    image.png

    三:这些代码主要用作加密和解密
    坑①:第149行一定要注意
    坑②:第255行跟256行的路径一定要对

    ok,完成,YEAH!!

    相关文章

      网友评论

          本文标题:RSA接口加密实现方法

          本文链接:https://www.haomeiwen.com/subject/xnhadxtx.html