// +---------------------------------------------------------------------- namespace Com; class WechatCrypt{ /** * 加密KEY * @var string */ private $cyptKey = ''; /** * 公众平台APPID * @var string */ private $appId = ''; /** * 构造方法,初始化加密KEY * @param string $key 加密KEY * @param string $appid 微信APP_KEY */ public function __construct($key, $appid){ if($key && $appid){ $this->appId = $appid; $this->cyptKey = base64_decode($key . '='); } else { throw new \Exception('缺少参数 APP_ID 和加密KEY!'); } } /** * 对明文进行加密 * @param string $text 需要加密的字符串 * @return string 密文字符串 */ public function encrypt($text){ //填充到明文之前的随机字符 $random = self::getRandomStr(16); //网络字节序 $size = pack("N", strlen($text)); //生成被加密字符串 $text = $random . $size . $text . $this->appId; //打开加密算法模块 $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); //使用PKCS7对明文进行补位 $text = self::PKCS7Encode($text, mcrypt_enc_get_key_size($td)); //初始化加密算法模块 mcrypt_generic_init($td, $this->cyptKey, substr($this->cyptKey, 0, 16)); //执行加密 $encrypt = mcrypt_generic($td, $text); //关闭加密算法模块 mcrypt_generic_deinit($td); mcrypt_module_close($td); //输出密文 return base64_encode($encrypt); } /** * 对密文进行解密 * @param string $encrypt 密文 * @return string 明文 */ public function decrypt($encrypt){ //BASE64解码 $encrypt = base64_decode($encrypt); //打开加密算法模块 $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); //初始化加密算法模块 mcrypt_generic_init($td, $this->cyptKey, substr($this->cyptKey, 0, 16)); //执行解密 $decrypt = mdecrypt_generic($td, $encrypt); //去除PKCS7补位 $decrypt = self::PKCS7Decode($decrypt, mcrypt_enc_get_key_size($td)); //关闭加密算法模块 mcrypt_generic_deinit($td); mcrypt_module_close($td); if(strlen($decrypt) < 16){ throw new \Exception("非法密文字符串!"); } //去除随机字符串 $decrypt = substr($decrypt, 16); //获取网络字节序 $size = unpack("N", substr($decrypt, 0, 4)); $size = $size[1]; //APP_ID $appid = substr($decrypt, $size + 4); //验证APP_ID if($appid !== $this->appId){ throw new \Exception("非法APP_ID!"); } //明文内容 $text = substr($decrypt, 4, $size); return $text; } /** * PKCS7填充字符 * @param string $text 被填充字符 * @param integer $size Block长度 */ private static function PKCS7Encode($text, $size){ //字符串长度 $str_size = strlen($text); //填充长度 $pad_size = $size - ($str_size % $size); $pad_size = $pad_size ? : $size; //填充的字符 $pad_chr = chr($pad_size); //执行填充 $text = str_pad($text, $str_size + $pad_size, $pad_chr, STR_PAD_RIGHT); return $text; } /** * 删除PKCS7填充的字符 * @param string $text 已填充的字符 * @param integer $size Block长度 */ private static function PKCS7Decode($text, $size){ //获取补位字符 $pad_str = ord(substr($text, -1)); if ($pad_str < 1 || $pad_str > $size) { return ''; } else { return substr($text, 0, strlen($text) - $pad_str); } } /** * 生成指定长度的字符串 * @param integer $len 字符串长度 * @return string 生成的字符串 */ private static function getRandomStr($len){ static $pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; $str = ''; $max = strlen($pol) - 1; for ($i = 0; $i < $len; $i++) { $str .= $pol[mt_rand(0, $max)]; } return $str; } }