Event.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. namespace wx\offiaccount;
  3. use Exception;
  4. use wx\Base;
  5. use wx\offiaccount\Event\Prpcrypt;
  6. use wx\offiaccount\Event\ErrorCode;
  7. use wx\offiaccount\Event\XMLParse;
  8. class Event extends Base
  9. {
  10. private $token;
  11. private $encodingAesKey;
  12. private $appId;
  13. /**
  14. * 构造函数
  15. * @param $token string 公众平台上,开发者设置的token
  16. * @param $encodingAesKey string 公众平台上,开发者设置的EncodingAESKey
  17. * @param $appId string 公众平台的appId
  18. */
  19. public function __construct($token, $encodingAesKey, $appId)
  20. {
  21. $this->token = $token;
  22. $this->encodingAesKey = $encodingAesKey;
  23. $this->appId = $appId;
  24. }
  25. /**
  26. * token验证
  27. */
  28. public function checkToken($token, $signature, $timestamp, $nonce)
  29. {
  30. $tmpArr = array($token, $timestamp, $nonce);
  31. sort($tmpArr, SORT_STRING); // 按字符串对数组进行排序
  32. $tmpStr = implode($tmpArr);
  33. $tmpStr = sha1($tmpStr);
  34. if ($tmpStr == $signature) {
  35. return true;
  36. } else {
  37. return false;
  38. }
  39. }
  40. /**
  41. * 将公众平台回复用户的消息加密打包.
  42. * <ol>
  43. * <li>对要发送的消息进行AES-CBC加密</li>
  44. * <li>生成安全签名</li>
  45. * <li>将消息密文和安全签名打包成xml格式</li>
  46. * </ol>
  47. *
  48. * @param $replyMsg string 公众平台待回复用户的消息,xml格式的字符串
  49. * @param $timeStamp string 时间戳,可以自己生成,也可以用URL参数的timestamp
  50. * @param $nonce string 随机串,可以自己生成,也可以用URL参数的nonce
  51. * @param &$encryptMsg string 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串,
  52. * 当return返回0时有效
  53. *
  54. * @return int 成功0,失败返回对应的错误码
  55. */
  56. public function encryptMsg($replyMsg, $timeStamp, $nonce, &$encryptMsg)
  57. {
  58. $pc = new Prpcrypt($this->encodingAesKey);
  59. //加密
  60. $array = $pc->encrypt($replyMsg, $this->appId);
  61. $ret = $array[0];
  62. if ($ret != 0) {
  63. return $ret;
  64. }
  65. if ($timeStamp == null) {
  66. $timeStamp = time();
  67. }
  68. $encrypt = $array[1];
  69. //生成安全签名
  70. $array = $this->getSHA1($this->token, $timeStamp, $nonce, $encrypt);
  71. $ret = $array[0];
  72. if ($ret != 0) {
  73. return $ret;
  74. }
  75. $signature = $array[1];
  76. //生成发送的xml
  77. $xmlparse = new XMLParse();
  78. $encryptMsg = $xmlparse->generate($encrypt, $signature, $timeStamp, $nonce);
  79. return ErrorCode::$OK;
  80. }
  81. /**
  82. * 检验消息的真实性,并且获取解密后的明文.
  83. * <ol>
  84. * <li>利用收到的密文生成安全签名,进行签名验证</li>
  85. * <li>若验证通过,则提取xml中的加密消息</li>
  86. * <li>对消息进行解密</li>
  87. * </ol>
  88. *
  89. * @param $msgSignature string 签名串,对应URL参数的msg_signature
  90. * @param $timestamp string 时间戳 对应URL参数的timestamp
  91. * @param $nonce string 随机串,对应URL参数的nonce
  92. * @param $postData string 密文,对应POST请求的数据
  93. * @param &$msg string 解密后的原文,当return返回0时有效
  94. *
  95. * @return int 成功0,失败返回对应的错误码
  96. */
  97. public function decryptMsg($msgSignature, $timestamp = null, $nonce, $postData, &$msg)
  98. {
  99. if (strlen($this->encodingAesKey) != 43) {
  100. return ErrorCode::$IllegalAesKey;
  101. }
  102. $pc = new Prpcrypt($this->encodingAesKey);
  103. //提取密文
  104. $xmlparse = new XMLParse();
  105. $array = $xmlparse->extract($postData);
  106. $ret = $array[0];
  107. if ($ret != 0) {
  108. return $ret;
  109. }
  110. if ($timestamp == null) {
  111. $timestamp = time();
  112. }
  113. $encrypt = $array[1];
  114. //验证安全签名
  115. $array = $this->getSHA1($this->token, $timestamp, $nonce, $encrypt);
  116. if ($ret != 0) {
  117. return $ret;
  118. }
  119. $signature = $array[1];
  120. if ($signature != $msgSignature) {
  121. return ErrorCode::$ValidateSignatureError;
  122. }
  123. $result = $pc->decrypt($encrypt, $this->appId);
  124. if ($result[0] != 0) {
  125. return $result[0];
  126. }
  127. $msg = $result[1];
  128. return ErrorCode::$OK;
  129. }
  130. /**
  131. * 用SHA1算法生成安全签名
  132. * @param string $token 票据
  133. * @param string $timestamp 时间戳
  134. * @param string $nonce 随机字符串
  135. * @param string $encrypt 密文消息
  136. */
  137. public function getSHA1($token, $timestamp, $nonce, $encrypt_msg)
  138. {
  139. //排序
  140. try {
  141. $array = array($encrypt_msg, $token, $timestamp, $nonce);
  142. sort($array, SORT_STRING);
  143. $str = implode($array);
  144. return array(ErrorCode::$OK, sha1($str));
  145. } catch (Exception $e) {
  146. //print $e . "\n";
  147. return array(ErrorCode::$ComputeSignatureError, null);
  148. }
  149. }
  150. }