当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP的RSA加密解密方法以及开发接口使用

发布:smiling 来源: PHP粉丝网  添加日期:2021-09-03 11:30:56 浏览: 评论:0 

网络安全问题很重要,尤其是保证数据安全,遇到很多在写接口的程序员直接都是明文数据传输,在我看来这是很不专业的,本人提倡经过接口的数据都要进行加密解密之后进行使用。

这篇文章主要介绍使用PHP开发接口,数据实现RSA加密解密后使用,实例分析了PHP自定义RSA类实现加密与解密的技巧,非常具有实用价值,需要的朋友可以参考下。

简单介绍RSA

RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。但是有不少新手对它不太了解。下面仅作简要介绍。RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。RSA的安全基于大数分解的难度。其公钥和私钥是一对大素数(100到200位十进制数或更大)的函数,从一个公钥和密文恢复出明文的难度,等价于分解两个大素数之积(这是公认的数学难题)。

下面为具体类、实例:

  1. <?php  
  2.    
  3. /**  
  4.  * RSA算法类  
  5.  * 签名及密文编码:base64字符串/十六进制字符串/二进制字符串流  
  6.  * 填充方式: PKCS1Padding(加解密)/NOPadding(解密)  
  7.  *  
  8.  * Notice:Only accepts a single block. Block size is equal to the RSA key size!  
  9.  * 如密钥长度为1024 bit,则加密时数据需小于128字节,加上PKCS1Padding本身的11字节信息,所以明文需小于117字节  
  10.  *  
  11.  * @author: ZHIHUA_WEI  
  12.  * @version: 1.0.0  
  13.  * @date: 2017/06/30  
  14.  */ 
  15. class RSA  
  16. {  
  17.   private $pubKey = null;  
  18.   private $priKey = null;  
  19.    
  20.   /**  
  21.    * 构造函数  
  22.    *  
  23.    * @param string 公钥文件(验签和加密时传入)  
  24.    * @param string 私钥文件(签名和解密时传入)  
  25.    */ 
  26.   public function __construct($public_key_file = ''$private_key_file = '')  
  27.   {  
  28.     if ($public_key_file) {  
  29.       $this->_getPublicKey($public_key_file);  
  30.     }  
  31.     if ($private_key_file) {  
  32.       $this->_getPrivateKey($private_key_file);  
  33.     }  
  34.   }  
  35.    
  36.   // 私有方法  
  37.   /**  
  38.    * 自定义错误处理  
  39.    */ 
  40.   private function _error($msg)  
  41.   {  
  42.     die('RSA Error:' . $msg); //TODO  
  43.   }  
  44.    
  45.   /**  
  46.    * 检测填充类型  
  47.    * 加密只支持PKCS1_PADDING  
  48.    * 解密支持PKCS1_PADDING和NO_PADDING  
  49.    *  
  50.    * @param int 填充模式  
  51.    * @param string 加密en/解密de  
  52.    * @return bool  
  53.    */ 
  54.   private function _checkPadding($padding$type)  
  55.   {  
  56.     if ($type == 'en') {  
  57.       switch ($padding) {  
  58.         case OPENSSL_PKCS1_PADDING:  
  59.           $ret = true;  
  60.           break;  
  61.         default:  
  62.           $ret = false;  
  63.       }  
  64.     } else {  
  65.       switch ($padding) {  
  66.         case OPENSSL_PKCS1_PADDING:  
  67.         case OPENSSL_NO_PADDING:  
  68.           $ret = true;  
  69.           break;  
  70.         default:  
  71.           $ret = false;  
  72.       }  
  73.     }  
  74.     return $ret;  
  75.   }  
  76.    
  77.   private function _encode($data$code)  
  78.   {  
  79.     switch (strtolower($code)) {  
  80.       case 'base64':  
  81.         $data = base64_encode('' . $data);  
  82.         break;  
  83.       case 'hex':  
  84.         $data = bin2hex($data);  
  85.         break;  
  86.       case 'bin':  
  87.       default:  
  88.     }  
  89.     return $data;  
  90.   }  
  91.    
  92.   private function _decode($data$code)  
  93.   {  
  94.     switch (strtolower($code)) {  
  95.       case 'base64':  
  96.         $data = base64_decode($data);  
  97.         break;  
  98.       case 'hex':  
  99.         $data = $this->_hex2bin($data);  
  100.         break;  
  101.       case 'bin':  
  102.       default:  
  103.     }  
  104.     return $data;  
  105.   }  
  106.    
  107.   private function _getPublicKey($file)  
  108.   {  
  109.     $key_content = $this->_readFile($file);  
  110.     if ($key_content) {  
  111.       $this->pubKey = openssl_get_publickey($key_content);  
  112.     }  
  113.   }  
  114.    
  115.   private function _getPrivateKey($file)  
  116.   {  
  117.     $key_content = $this->_readFile($file);  
  118.     if ($key_content) {  
  119.       $this->priKey = openssl_get_privatekey($key_content);  
  120.     }  
  121.   }  
  122.    
  123.   private function _readFile($file)  
  124.   {  
  125.     $ret = false;  
  126.     if (!file_exists($file)) {  
  127.       $this->_error("The file {$file} is not exists");  
  128.     } else {  
  129.       $ret = file_get_contents($file);  
  130.     }  
  131.     return $ret;  
  132.   }  
  133.    
  134.   private function _hex2bin($hex = false)  
  135.   {  
  136.     $ret = $hex !== false && preg_match('/^[0-9a-fA-F]+$/i'$hex) ? pack("H*"$hex) : false;  
  137.     return $ret;  
  138.   }  
  139.    
  140.   /**  
  141.    * 生成签名  
  142.    *  
  143.    * @param string 签名材料  
  144.    * @param string 签名编码(base64/hex/bin)  
  145.    * @return 签名值  
  146.    */ 
  147.   public function sign($data$code = 'base64')  
  148.   {  
  149.     $ret = false;  
  150.     if (openssl_sign($data$ret$this->priKey)) {  
  151.       $ret = $this->_encode($ret$code);  
  152.     }  
  153.     return $ret;  
  154.   }  
  155.    
  156.   /**  
  157.    * 验证签名  
  158.    *  
  159.    * @param string 签名材料  
  160.    * @param string 签名值  
  161.    * @param string 签名编码(base64/hex/bin)  
  162.    * @return bool  
  163.    */ 
  164.   public function verify($data$sign$code = 'base64')  
  165.   {  
  166.     $ret = false;  
  167.     $sign = $this->_decode($sign$code);  
  168.     if ($sign !== false) {  
  169.       switch (openssl_verify($data$sign$this->pubKey)) {  
  170.         case 1:  
  171.           $ret = true;  
  172.           break;  
  173.         case 0:  
  174.         case -1:  
  175.         default:  
  176.           $ret = false;  
  177.       }  
  178.     }  
  179.     return $ret;  
  180.   }  
  181.    
  182.   /**  
  183.    * 加密  
  184.    *  
  185.    * @param string 明文  
  186.    * @param string 密文编码(base64/hex/bin)  
  187.    * @param int 填充方式(貌似php有bug,所以目前仅支持OPENSSL_PKCS1_PADDING)  
  188.    * @return string 密文  
  189.    */ 
  190.   public function encrypt($data$code = 'base64'$padding = OPENSSL_PKCS1_PADDING)  
  191.   {  
  192.     $ret = false;  
  193.     if (!$this->_checkPadding($padding'en')) $this->_error('padding error');  
  194.     if (openssl_public_encrypt($data$result$this->pubKey, $padding)) {  
  195.       $ret = $this->_encode($result$code);  
  196.     }  
  197.     return $ret;  
  198.   }  
  199.    
  200.   /**  
  201.    * 解密  
  202.    *  
  203.    * @param string 密文  
  204.    * @param string 密文编码(base64/hex/bin)  
  205.    * @param int 填充方式(OPENSSL_PKCS1_PADDING / OPENSSL_NO_PADDING)  
  206.    * @param bool 是否翻转明文(When passing Microsoft CryptoAPI-generated RSA cyphertext, revert the bytes in the block)  
  207.    * @return string 明文  
  208.    */ 
  209.   public function decrypt($data$code = 'base64'$padding = OPENSSL_PKCS1_PADDING, $rev = false)  
  210.   {  
  211.     $ret = false;  
  212.     $data = $this->_decode($data$code);  
  213.     if (!$this->_checkPadding($padding'de')) $this->_error('padding error');  
  214.     if ($data !== false) {  
  215.       if (openssl_private_decrypt($data$result$this->priKey, $padding)) {  
  216.         $ret = $rev ? rtrim(strrev($result), "\0") : '' . $result;  
  217.       }  
  218.     }  
  219.     return $ret;  
  220.   }  

此为具体的RSA类

  1. <?php  
  2. /**  
  3.  * Author: Wei ZhiHua  
  4.  * Date: 2017/6/30 0030  
  5.  * Time: 上午 10:15  
  6.  */ 
  7. header('Content-Type:text/html;Charset=utf-8;');  
  8. include "RSA.php";  
  9. echo '<pre>';  
  10.    
  11. $pubfile = 'D:\WWW\test\rsa_public_key.pem';  
  12. $prifile = 'D:\WWW\test\rsa_private_key.pem';  
  13. $rsa = new RSA($pubfile$prifile);  
  14. $rst = array(  
  15.   'ret' => 200,  
  16.   'code' => 1,  
  17.   'data' => array(1, 2, 3, 4, 5, 6),  
  18.   'msg' => "success",  
  19. );  
  20. $ex = json_encode($rst);  
  21. //加密  
  22. $ret_e = $rsa->encrypt($ex);  
  23. //解密  
  24. $ret_d = $rsa->decrypt($ret_e);  
  25. echo $ret_e;  
  26. echo '<pre>';  
  27. echo $ret_d;  
  28. echo '<pre>';   
  29. $a = 'test';  
  30. //签名  
  31. $x = $rsa->sign($a);  
  32. //验证  
  33. $y = $rsa->verify($a$x);  
  34. var_dump($x$y);  
  35. exit;

Tags: RSA加密解密 PHP加密解密

分享到: