当前位置:首页 > PHP教程 > php类库 > 列表

php实现RSA加密类实例

发布:smiling 来源: PHP粉丝网  添加日期:2021-05-18 20:28:09 浏览: 评论:0 

这篇文章主要介绍了php实现RSA加密类,实例分析了php自定义RSA类实现加密与解密的技巧,非常具有实用价值,需要的朋友可以参考下

本文实例讲述了php实现RSA加密类,分享给大家供大家参考,具体分析如下:

通过openssl实现的签名、验签、非对称加解密,需要配合x.509证书(如crt和pem)文件使用。

由于各种原因,该类并不十分完善,欢迎各种测试!

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

测试demo:

  1. <?php  
  2. header('Content-Type:text/html;Charset=utf-8;');  
  3. include "rsa.php";  
  4. echo '<pre>';  
  5. $a = isset($_GET['a']) ? $_GET['a'] : '测试123';  
  6. //////////////////////////////////////  
  7. $pubfile = 'E:\ssl\cert\pwd.crt';  
  8. $prifile = 'E:\ssl\cert\pwd.pem';  
  9. $m = new RSA($pubfile$prifile);  
  10. $x = $m->sign($a);  
  11. $y = $m->verify($a$x);  
  12. var_dump($x$y);  
  13. $x = $m->encrypt($a);  
  14. $y = $m->decrypt($x);  
  15. var_dump($x$y);

Tags: RSA加密类

分享到: