WechatCrypt.class.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: 麦当苗儿 <zuojiazi.cn@gmail.com> <http://www.zjzit.cn>
  10. // +----------------------------------------------------------------------
  11. namespace Com;
  12. class WechatCrypt{
  13. /**
  14. * 加密KEY
  15. * @var string
  16. */
  17. private $cyptKey = '';
  18. /**
  19. * 公众平台APPID
  20. * @var string
  21. */
  22. private $appId = '';
  23. /**
  24. * 构造方法,初始化加密KEY
  25. * @param string $key 加密KEY
  26. * @param string $appid 微信APP_KEY
  27. */
  28. public function __construct($key, $appid){
  29. if($key && $appid){
  30. $this->appId = $appid;
  31. $this->cyptKey = base64_decode($key . '=');
  32. } else {
  33. throw new \Think\Exception('缺少参数 APP_ID 和加密KEY!');
  34. }
  35. }
  36. /**
  37. * 对明文进行加密
  38. * @param string $text 需要加密的字符串
  39. * @return string 密文字符串
  40. */
  41. public function encrypt($text){
  42. //填充到明文之前的随机字符
  43. $random = self::getRandomStr(16);
  44. //网络字节序
  45. $size = pack("N", strlen($text));
  46. //生成被加密字符串
  47. $text = $random . $size . $text . $this->appId;
  48. //打开加密算法模块
  49. $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
  50. //使用PKCS7对明文进行补位
  51. $text = self::PKCS7Encode($text, mcrypt_enc_get_key_size($td));
  52. //初始化加密算法模块
  53. mcrypt_generic_init($td, $this->cyptKey, substr($this->cyptKey, 0, 16));
  54. //执行加密
  55. $encrypt = mcrypt_generic($td, $text);
  56. //关闭加密算法模块
  57. mcrypt_generic_deinit($td);
  58. mcrypt_module_close($td);
  59. //输出密文
  60. return base64_encode($encrypt);
  61. }
  62. /**
  63. * 对密文进行解密
  64. * @param string $encrypt 密文
  65. * @return string 明文
  66. */
  67. public function decrypt($encrypt){
  68. //BASE64解码
  69. $encrypt = base64_decode($encrypt);
  70. //打开加密算法模块
  71. $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
  72. //初始化加密算法模块
  73. mcrypt_generic_init($td, $this->cyptKey, substr($this->cyptKey, 0, 16));
  74. //执行解密
  75. $decrypt = mdecrypt_generic($td, $encrypt);
  76. //去除PKCS7补位
  77. $decrypt = self::PKCS7Decode($decrypt, mcrypt_enc_get_key_size($td));
  78. //关闭加密算法模块
  79. mcrypt_generic_deinit($td);
  80. mcrypt_module_close($td);
  81. if(strlen($decrypt) < 16){
  82. throw new \Think\Exception("非法密文字符串!");
  83. }
  84. //去除随机字符串
  85. $decrypt = substr($decrypt, 16);
  86. //获取网络字节序
  87. $size = unpack("N", substr($decrypt, 0, 4));
  88. $size = $size[1];
  89. //APP_ID
  90. $appid = substr($decrypt, $size + 4);
  91. //验证APP_ID
  92. if($appid !== $this->appId){
  93. throw new \Think\Exception("非法APP_ID!");
  94. }
  95. //明文内容
  96. $text = substr($decrypt, 4, $size);
  97. return $text;
  98. }
  99. /**
  100. * PKCS7填充字符
  101. * @param string $text 被填充字符
  102. * @param integer $size Block长度
  103. */
  104. private static function PKCS7Encode($text, $size){
  105. //字符串长度
  106. $str_size = strlen($text);
  107. //填充长度
  108. $pad_size = $size - ($str_size % $size);
  109. $pad_size = $pad_size ? : $size;
  110. //填充的字符
  111. $pad_chr = chr($pad_size);
  112. //执行填充
  113. $text = str_pad($text, $str_size + $pad_size, $pad_chr, STR_PAD_RIGHT);
  114. return $text;
  115. }
  116. /**
  117. * 删除PKCS7填充的字符
  118. * @param string $text 已填充的字符
  119. * @param integer $size Block长度
  120. */
  121. private static function PKCS7Decode($text, $size){
  122. //获取补位字符
  123. $pad_str = ord(substr($text, -1));
  124. if ($pad_str < 1 || $pad_str > $size) {
  125. return '';
  126. } else {
  127. return substr($text, 0, strlen($text) - $pad_str);
  128. }
  129. }
  130. /**
  131. * 生成指定长度的字符串
  132. * @param integer $len 字符串长度
  133. * @return string 生成的字符串
  134. */
  135. private static function getRandomStr($len){
  136. static $pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
  137. $str = '';
  138. $max = strlen($pol) - 1;
  139. for ($i = 0; $i < $len; $i++) {
  140. $str .= $pol[mt_rand(0, $max)];
  141. }
  142. return $str;
  143. }
  144. }