WXBizMsgCrypt.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. /**
  3. * 企业微信回调消息加解密示例代码.
  4. *
  5. * @copyright Copyright (c) 1998-2014 Tencent Inc.
  6. */
  7. namespace WeWork;
  8. class WXBizMsgCrypt
  9. {
  10. private $m_sToken;
  11. private $m_sEncodingAesKey;
  12. private $m_sReceiveId;
  13. /**
  14. * 构造函数
  15. *
  16. * @param $token string 开发者设置的token
  17. * @param $encodingAesKey string 开发者设置的EncodingAESKey
  18. * @param $receiveId string, 不同应用场景传不同的id
  19. */
  20. public function __construct($token, $encodingAesKey, $receiveId)
  21. {
  22. $this->m_sToken = $token;
  23. $this->m_sEncodingAesKey = $encodingAesKey;
  24. $this->m_sReceiveId = $receiveId;
  25. }
  26. /*
  27. *验证URL
  28. *@param sMsgSignature: 签名串,对应URL参数的msg_signature
  29. *@param sTimeStamp: 时间戳,对应URL参数的timestamp
  30. *@param sNonce: 随机串,对应URL参数的nonce
  31. *@param sEchoStr: 随机串,对应URL参数的echostr
  32. *@param sReplyEchoStr: 解密之后的echostr,当return返回0时有效
  33. *@return:成功0,失败返回对应的错误码
  34. */
  35. public function VerifyURL($sMsgSignature, $sTimeStamp, $sNonce, $sEchoStr, &$sReplyEchoStr)
  36. {
  37. if (strlen($this->m_sEncodingAesKey) != 43) {
  38. return ErrorCode::$IllegalAesKey;
  39. }
  40. $pc = new Prpcrypt($this->m_sEncodingAesKey);
  41. //verify msg_signature
  42. $sha1 = new SHA1;
  43. $array = $sha1->getSHA1($this->m_sToken, $sTimeStamp, $sNonce, $sEchoStr);
  44. $ret = $array[0];
  45. if ($ret != 0) {
  46. return $ret;
  47. }
  48. $signature = $array[1];
  49. if ($signature != $sMsgSignature) {
  50. return ErrorCode::$ValidateSignatureError;
  51. }
  52. $result = $pc->decrypt($sEchoStr, $this->m_sReceiveId);
  53. if ($result[0] != 0) {
  54. return $result[0];
  55. }
  56. $sReplyEchoStr = $result[1];
  57. return ErrorCode::$OK;
  58. }
  59. /**
  60. * 将公众平台回复用户的消息加密打包.
  61. * <ol>
  62. * <li>对要发送的消息进行AES-CBC加密</li>
  63. * <li>生成安全签名</li>
  64. * <li>将消息密文和安全签名打包成xml格式</li>
  65. * </ol>
  66. *
  67. * @param string $sReplyMsg 公众平台待回复用户的消息,xml格式的字符串
  68. * @param string $sTimeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp
  69. * @param string $sNonce 随机串,可以自己生成,也可以用URL参数的nonce
  70. * @param string &$sEncryptMsg 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串. 当return返回0时有效
  71. *
  72. * @return int 成功0,失败返回对应的错误码
  73. */
  74. public function EncryptMsg($sReplyMsg, $sTimeStamp, $sNonce, &$sEncryptMsg)
  75. {
  76. $pc = new Prpcrypt($this->m_sEncodingAesKey);
  77. //加密
  78. $array = $pc->encrypt($sReplyMsg, $this->m_sReceiveId);
  79. $ret = $array[0];
  80. if ($ret != 0) {
  81. return $ret;
  82. }
  83. if ($sTimeStamp == null) {
  84. $sTimeStamp = time();
  85. }
  86. $encrypt = $array[1];
  87. //生成安全签名
  88. $sha1 = new SHA1;
  89. $array = $sha1->getSHA1($this->m_sToken, $sTimeStamp, $sNonce, $encrypt);
  90. $ret = $array[0];
  91. if ($ret != 0) {
  92. return $ret;
  93. }
  94. $signature = $array[1];
  95. //生成发送的xml
  96. $xmlParse = new XMLParse;
  97. $sEncryptMsg = $xmlParse->generate($encrypt, $signature, $sTimeStamp, $sNonce);
  98. return ErrorCode::$OK;
  99. }
  100. /**
  101. * 检验消息的真实性,并且获取解密后的明文.
  102. * <ol>
  103. * <li>利用收到的密文生成安全签名,进行签名验证</li>
  104. * <li>若验证通过,则提取xml中的加密消息</li>
  105. * <li>对消息进行解密</li>
  106. * </ol>
  107. *
  108. * @param string $sMsgSignature 签名串,对应URL参数的msg_signature
  109. * @param string $sTimeStamp 时间戳 对应URL参数的timestamp
  110. * @param string $sNonce 随机串,对应URL参数的nonce
  111. * @param string $sPostData 密文,对应POST请求的数据
  112. * @param string & $sMsg 解密后的原文,当return返回0时有效
  113. *
  114. * @return int 成功0,失败返回对应的错误码
  115. */
  116. public function DecryptMsg($sMsgSignature, $sTimeStamp, $sNonce, $sPostData, &$sMsg)
  117. {
  118. if (strlen($this->m_sEncodingAesKey) != 43) {
  119. return ErrorCode::$IllegalAesKey;
  120. }
  121. $pc = new Prpcrypt($this->m_sEncodingAesKey);
  122. //提取密文
  123. $xmlParse = new XMLParse;
  124. $array = $xmlParse->extract($sPostData);
  125. $ret = $array[0];
  126. if ($ret != 0) {
  127. return $ret;
  128. }
  129. if ($sTimeStamp == null) {
  130. $sTimeStamp = time();
  131. }
  132. $encrypt = $array[1];
  133. //验证安全签名
  134. $sha1 = new SHA1;
  135. $array = $sha1->getSHA1($this->m_sToken, $sTimeStamp, $sNonce, $encrypt);
  136. $ret = $array[0];
  137. if ($ret != 0) {
  138. return $ret;
  139. }
  140. $signature = $array[1];
  141. if ($signature != $sMsgSignature) {
  142. return ErrorCode::$ValidateSignatureError;
  143. }
  144. $result = $pc->decrypt($encrypt, $this->m_sReceiveId);
  145. if ($result[0] != 0) {
  146. return $result[0];
  147. }
  148. $sMsg = $result[1];
  149. return ErrorCode::$OK;
  150. }
  151. }