WxDecryptFacadeRepository.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. namespace App\Repositories\Eloquent;
  3. use App\Repositories\Contracts\WxDecryptInterface;
  4. /**
  5. *
  6. * @author lilin
  7. *
  8. */
  9. class WxDecryptFacadeRepository extends BaseRepository implements WxDecryptInterface
  10. {
  11. public $appid;
  12. public $encodingAesKey;
  13. public $token;
  14. public function __construct()
  15. {
  16. $this->appid = env('MP_APPID');
  17. $this->encodingAesKey = env('MP_ENCODINGAESKEY');
  18. $this->token = env('MP_TOKEN');
  19. }
  20. public function xmlToArray($xml)
  21. {
  22. libxml_disable_entity_loader(true);
  23. $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  24. return $values;
  25. }
  26. public function arrayToXml(array $config)
  27. {
  28. $xml = "<xml>";
  29. foreach ($config as $key=>$val)
  30. {
  31. if (is_numeric($val)){
  32. $xml.="<".$key.">".$val."</".$key.">";
  33. }else{
  34. $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
  35. }
  36. }
  37. $xml.="</xml>";
  38. return $xml;
  39. }
  40. public function getSHA1($timestamp, $nonce, $encrypt_msg)
  41. {
  42. $array = array($encrypt_msg, $this->token, $timestamp, $nonce);
  43. sort($array, SORT_STRING);
  44. $str = implode($array);
  45. return sha1($str);
  46. }
  47. public function sendWxHttp($url, $content)
  48. {
  49. //转成微信需要的格式
  50. $content = json_encode($content,JSON_UNESCAPED_UNICODE);
  51. $ch = curl_init();
  52. curl_setopt($ch, CURLOPT_URL, $url);
  53. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
  54. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  55. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  56. curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
  57. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  58. curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  59. curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
  60. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  61. $tmpInfo = curl_exec($ch);
  62. if (curl_errno($ch)) {
  63. return curl_error($ch);
  64. }
  65. curl_close($ch);
  66. return json_decode($tmpInfo, true);
  67. }
  68. public function decryptMsg($array, $msgSignature, $timestamp, $nonce)
  69. {
  70. self::setLog(self::TYPENAME, $this->startTime(), ['array'=>$array, 'msgSignature'=>$msgSignature, 'timestamp'=>$timestamp, 'nonce'=>$nonce]);
  71. if (strlen($this->encodingAesKey) != 43) {
  72. return 'encodingAesKey 不等 43个';
  73. }
  74. // 提取密文
  75. if ($timestamp == null) {
  76. $timestamp = time();
  77. }
  78. $encrypt = $array['Encrypt'];
  79. // 验证安全签名
  80. $signature = $this->getSHA1($timestamp, $nonce, $encrypt);
  81. if ($signature != $msgSignature) {
  82. return '不相等 signature:'.$signature.' msgSignature:'.$msgSignature;
  83. }
  84. return $this->decrypt($encrypt, $this->appid);
  85. }
  86. public function decrypt($encrypted)
  87. {
  88. $key = $this->_makeKey();
  89. $ciphertext_dec = base64_decode($encrypted);
  90. $iv = substr($key, 0, 16);
  91. $decrypted = openssl_decrypt($ciphertext_dec, 'AES-256-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
  92. $result = $this->decode($decrypted);
  93. $content = substr($result, 16, strlen($result));
  94. $len_list = unpack("N", substr($content, 0, 4));
  95. $xml_len = $len_list[1];
  96. $xml_content = substr($content, 4, $xml_len);
  97. $from_appid = substr($content, $xml_len + 4);
  98. return self::xmlToArray($xml_content);
  99. }
  100. public function decode($text)
  101. {
  102. $pad = ord(substr($text, - 1));
  103. if ($pad < 1 || $pad > 32) {
  104. $pad = 0;
  105. }
  106. return substr($text, 0, (strlen($text) - $pad));
  107. }
  108. /**
  109. * 合并Key
  110. *
  111. * @return string
  112. */
  113. private function _makeKey()
  114. {
  115. return base64_decode($this->encodingAesKey . "=");
  116. }
  117. }