常用对称加密类
对称加密
1 <?php 2 3 /** 4 * 常用对称加密算法类 5 * 支持密钥:64/128/256 bit(字节长度8/16/32) 6 * 支持算法:DES/AES(根据密钥长度自动匹配使用:DES:64bit AES:128/256bit) 7 * 支持模式:CBC/ECB/OFB/CFB 8 * 密文编码:base64字符串/十六进制字符串/二进制字符串流 9 * 填充方式: PKCS5Padding(DES) 10 * 11 * @author: linvo 12 * @version: 1.0.0 13 * @date: 2013/1/10 14 */ 15 class Xcrypt{ 16 17 private $mcrypt; 18 private $key; 19 private $mode; 20 private $iv; 21 private $blocksize; 22 23 /** 24 * 构造函数 25 * 26 * @param string 密钥 27 * @param string 模式 28 * @param string 向量("off":不使用 / "auto":自动 / 其他:指定值,长度同密钥) 29 */ 30 public function __construct($key, $mode = 'cbc', $iv = "off"){ 31 switch (strlen($key)){ 32 case 8: 33 $this->mcrypt = MCRYPT_DES; 34 break; 35 case 16: 36 $this->mcrypt = MCRYPT_RIJNDAEL_128; 37 break; 38 case 32: 39 $this->mcrypt = MCRYPT_RIJNDAEL_256; 40 break; 41 default: 42 die("Key size must be 8/16/32"); 43 } 44 45 $this->key = $key; 46 47 switch (strtolower($mode)){ 48 case 'ofb': 49 $this->mode = MCRYPT_MODE_OFB; 50 if ($iv == 'off') die('OFB must give a IV'); //OFB必须有向量 51 break; 52 case 'cfb': 53 $this->mode = MCRYPT_MODE_CFB; 54 if ($iv == 'off') die('CFB must give a IV'); //CFB必须有向量 55 break; 56 case 'ecb': 57 $this->mode = MCRYPT_MODE_ECB; 58 $iv = 'off'; //ECB不需要向量 59 break; 60 case 'cbc': 61 default: 62 $this->mode = MCRYPT_MODE_CBC; 63 } 64 65 switch (strtolower($iv)){ 66 case "off": 67 $this->iv = null; 68 break; 69 case "auto": 70 $source = PHP_OS=='WINNT' ? MCRYPT_RAND : MCRYPT_DEV_RANDOM; 71 $this->iv = mcrypt_create_iv(mcrypt_get_block_size($this->mcrypt, $this->mode), $source); 72 break; 73 default: 74 $this->iv = $iv; 75 } 76 77 78 } 79 80 /** 81 * 获取向量值 82 * @param string 向量值编码(base64/hex/bin) 83 * @return string 向量值 84 */ 85 public function getIV($code = 'base64'){ 86 switch ($code){ 87 case 'base64': 88 $ret = base64_encode($this->iv); 89 break; 90 case 'hex': 91 $ret = bin2hex($this->iv); 92 break; 93 case 'bin': 94 default: 95 $ret = $this->iv; 96 } 97 return $ret; 98 } 99 100 /** 101 * 加密 102 * @param string 明文 103 * @param string 密文编码(base64/hex/bin) 104 * @return string 密文 105 */ 106 public function encrypt($str, $code = 'base64'){ 107 if ($this->mcrypt == MCRYPT_DES) $str = $this->_pkcs5Pad($str); 108 109 if (isset($this->iv)) { 110 $result = mcrypt_encrypt($this->mcrypt, $this->key, $str, $this->mode, $this->iv); 111 } else { 112 @$result = mcrypt_encrypt($this->mcrypt, $this->key, $str, $this->mode); 113 } 114 115 switch ($code){ 116 case 'base64': 117 $ret = base64_encode($result); 118 break; 119 case 'hex': 120 $ret = bin2hex($result); 121 break; 122 case 'bin': 123 default: 124 $ret = $result; 125 } 126 127 return $ret; 128 129 } 130 131 /** 132 * 解密 133 * @param string 密文 134 * @param string 密文编码(base64/hex/bin) 135 * @return string 明文 136 */ 137 public function decrypt($str, $code = "base64"){ 138 $ret = false; 139 140 switch ($code){ 141 case 'base64': 142 $str = base64_decode($str); 143 break; 144 case 'hex': 145 $str = $this->_hex2bin($str); 146 break; 147 case 'bin': 148 default: 149 } 150 151 if ($str !== false){ 152 if (isset($this->iv)) { 153 $ret = mcrypt_decrypt($this->mcrypt, $this->key, $str, $this->mode, $this->iv); 154 } else { 155 @$ret = mcrypt_decrypt($this->mcrypt, $this->key, $str, $this->mode); 156 } 157 if ($this->mcrypt == MCRYPT_DES) $ret = $this->_pkcs5Unpad($ret); 158 $ret = trim($ret); 159 } 160 161 return $ret; 162 } 163 164 private function _pkcs5Pad($text){ 165 $this->blocksize = mcrypt_get_block_size($this->mcrypt, $this->mode); 166 $pad = $this->blocksize - (strlen($text) % $this->blocksize); 167 return $text . str_repeat(chr($pad), $pad); 168 } 169 170 private function _pkcs5Unpad($text){ 171 $pad = ord($text{strlen($text) - 1}); 172 if ($pad > strlen($text)) return false; 173 if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false; 174 $ret = substr($text, 0, -1 * $pad); 175 return $ret; 176 } 177 178 private function _hex2bin($hex = false){ 179 $ret = $hex !== false && preg_match('/^[0-9a-fA-F]+$/i', $hex) ? pack("H*", $hex) : false; 180 return $ret; 181 } 182 183 184 185 } 186 187 188 189 header('Content-Type:text/html;Charset=utf-8;'); 190 191 echo '<pre>'; 192 ////////////////////////////////////// 193 $a = isset($_GET['a']) ? $_GET['a'] : '<uid>441323198511201032</uid><pswd>851120</pswd><gid>12682</gid><date>2018-11-30</date>'; 194 195 //密钥 196 $key = 'EW2sdfkj'; //64 bit 197 198 //设置模式和IV 199 $m = new Xcrypt($key, 'ecb', 'auto'); 200 //加密 201 $b = $m->encrypt($a, 'hex'); 202 203 echo '加密后:'; 204 var_dump($b);