WxBizDecrypt.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: jianjun
  5. * Date: 2016/11/17
  6. * Time: 17:12
  7. */
  8. namespace api\libs;
  9. use yii\base\Exception;
  10. /**
  11. * 微信小程序加密解密包
  12. * Class WxBizDecrypt
  13. * @package api\lib
  14. */
  15. class WxBizDecrypt
  16. {
  17. public static $OK = 0;
  18. public static $IllegalAesKey = -41001;
  19. public static $IllegalIv = -41002;
  20. public static $IllegalBuffer = -41003;
  21. public static $DecodeBase64Error = -41004;
  22. public static $IllegalSessionKey = -41005;
  23. public static $block_size = 16;
  24. public static $appid = '';
  25. public static $appSecret = '';
  26. /**
  27. * 获取SessionKey 以及Openid
  28. * SessionKey 获取更多加密信息,如unionId
  29. * @param $code
  30. * @return Int
  31. */
  32. static function getSessionkey($code,&$data){
  33. $url = "https://api.weixin.qq.com/sns/jscode2session?appid=".self::$appid."&secret=".self::$appSecret."&js_code=$code&grant_type=authorization_code";
  34. $result = self::getHtml($url);
  35. $resultObj = json_decode($result);
  36. if($resultObj== null){
  37. return self::$IllegalSessionKey;
  38. }
  39. $data = $result;
  40. return self::$OK;
  41. }
  42. protected static function getHtml($url){
  43. $ch = curl_init();
  44. $timeout = 5;
  45. curl_setopt($ch, CURLOPT_URL, $url);
  46. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  47. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  48. $result = curl_exec($ch);
  49. curl_close($ch);
  50. return $result;
  51. }
  52. /**
  53. * 检验数据的真实性,并且获取解密后的明文.
  54. * @param $encryptedData string 加密的用户数据
  55. * @param $iv string 与用户数据一同返回的初始向量
  56. * @param $data string 解密后的原文
  57. *
  58. * @return int 成功0,失败返回对应的错误码
  59. */
  60. static function decryptData( $encryptedData, $iv,$sessionKey, &$data )
  61. {
  62. if (strlen($sessionKey) != 24) {
  63. return self::$IllegalAesKey;
  64. }
  65. $aesKey=base64_decode($sessionKey);
  66. if (strlen($iv) != 24) {
  67. return self::$IllegalIv;
  68. }
  69. $aesIV=base64_decode($iv);
  70. $aesCipher=base64_decode($encryptedData);
  71. $result = self::decrypt($aesCipher,$aesIV,$aesKey);
  72. if ($result[0] != 0) {
  73. return $result[0];
  74. }
  75. $dataObj=json_decode( $result[1] );
  76. if( $dataObj == NULL )
  77. {
  78. return self::$IllegalBuffer;
  79. }
  80. if( $dataObj->watermark->appid != self::$appid )
  81. {
  82. return self::$IllegalBuffer;
  83. }
  84. $data = $result[1];
  85. return self::$OK;
  86. }
  87. /**
  88. * 对需要加密的明文进行填充补位
  89. * @param $text 需要进行填充补位操作的明文
  90. * @return 补齐明文字符串
  91. */
  92. static function encode( $text )
  93. {
  94. $text_length = strlen( $text );
  95. //计算需要填充的位数
  96. $amount_to_pad = self::$block_size - ( $text_length % self::$block_size );
  97. if ( $amount_to_pad == 0 ) {
  98. $amount_to_pad = self::$block_size;
  99. }
  100. //获得补位所用的字符
  101. $pad_chr = chr( $amount_to_pad );
  102. $tmp = "";
  103. for ( $index = 0; $index < $amount_to_pad; $index++ ) {
  104. $tmp .= $pad_chr;
  105. }
  106. return $text . $tmp;
  107. }
  108. /**
  109. * 对解密后的明文进行补位删除
  110. * @param decrypted 解密后的明文
  111. * @return 删除填充补位后的明文
  112. */
  113. static function decode($text)
  114. {
  115. $pad = ord(substr($text, -1));
  116. if ($pad < 1 || $pad > 32) {
  117. $pad = 0;
  118. }
  119. return substr($text, 0, (strlen($text) - $pad));
  120. }
  121. /**
  122. * 对密文进行解密
  123. * @param string $aesCipher 需要解密的密文
  124. * @param string $aesIV 解密的初始向量
  125. * @return string 解密得到的明文
  126. */
  127. static function decrypt( $aesCipher, $aesIV ,$key)
  128. {
  129. try {
  130. $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
  131. mcrypt_generic_init($module, $key, $aesIV);
  132. //解密
  133. $decrypted = mdecrypt_generic($module, $aesCipher);
  134. mcrypt_generic_deinit($module);
  135. mcrypt_module_close($module);
  136. } catch (Exception $e) {
  137. return array(self::$IllegalBuffer, null);
  138. }
  139. try {
  140. //去除补位字符
  141. $result = self::decode($decrypted);
  142. } catch (Exception $e) {
  143. //print $e;
  144. return array(self::$IllegalBuffer, null);
  145. }
  146. return array(0, $result);
  147. }
  148. }