ClientResponseHandler.class.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. /**
  3. * 后台应答类
  4. * ============================================================================
  5. * api说明:
  6. * getKey()/setKey(),获取/设置密钥
  7. * getContent() / setContent(), 获取/设置原始内容
  8. * getParameter()/setParameter(),获取/设置参数值
  9. * getAllParameters(),获取所有参数
  10. * isTenpaySign(),是否威富通签名,true:是 false:否
  11. * getDebugInfo(),获取debug信息
  12. *
  13. * ============================================================================
  14. *
  15. */
  16. class ClientResponseHandler {
  17. /** MD5密钥 */
  18. var $key;
  19. /* 威富通RSA公钥 */
  20. var $public_rsa_key;
  21. var $signtype;
  22. /** 应答的参数 */
  23. var $parameters;
  24. /** debug信息 */
  25. var $debugInfo;
  26. //原始内容
  27. var $content;
  28. function __construct() {
  29. $this->ClientResponseHandler();
  30. }
  31. function ClientResponseHandler() {
  32. $this->key = "";
  33. $this->public_rsa_key = "";
  34. $this->signtype = "";
  35. $this->parameters = array();
  36. $this->debugInfo = "";
  37. $this->content = "";
  38. }
  39. /**
  40. *获取密钥
  41. */
  42. function getKey() {
  43. return $this->key;
  44. }
  45. /**
  46. *设置密钥
  47. */
  48. function setKey($key) {
  49. $this->key = $key;
  50. }
  51. /*设置威富通公钥*/
  52. function setRSAKey($key) {
  53. $this->public_rsa_key = $key;
  54. }
  55. function setSignType($type) {
  56. $this->signtype = $type;
  57. }
  58. //设置原始内容
  59. function setContent($content) {
  60. $this->content = $content;
  61. libxml_disable_entity_loader(true);
  62. $xml = simplexml_load_string($this->content);
  63. $encode = $this->getXmlEncode($this->content);
  64. if($xml && $xml->children()) {
  65. foreach ($xml->children() as $node){
  66. //有子节点
  67. if($node->children()) {
  68. $k = $node->getName();
  69. $nodeXml = $node->asXML();
  70. $v = substr($nodeXml, strlen($k)+2, strlen($nodeXml)-2*strlen($k)-5);
  71. } else {
  72. $k = $node->getName();
  73. $v = (string)$node;
  74. }
  75. if($encode!="" && $encode != "UTF-8") {
  76. $k = iconv("UTF-8", $encode, $k);
  77. $v = iconv("UTF-8", $encode, $v);
  78. }
  79. $this->setParameter($k, $v);
  80. }
  81. }
  82. }
  83. //获取原始内容
  84. function getContent() {
  85. return $this->content;
  86. }
  87. /**
  88. *获取参数值
  89. */
  90. function getParameter($parameter) {
  91. return isset($this->parameters[$parameter])?$this->parameters[$parameter] : '';
  92. }
  93. /**
  94. *设置参数值
  95. */
  96. function setParameter($parameter, $parameterValue) {
  97. $this->parameters[$parameter] = $parameterValue;
  98. }
  99. /**
  100. *获取所有请求的参数
  101. *@return array
  102. */
  103. function getAllParameters() {
  104. return $this->parameters;
  105. }
  106. /**
  107. *是否威富通签名,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
  108. *true:是
  109. *false:否
  110. */
  111. function isTenpaySign() {
  112. $swiftpassSign = strtolower($this->getParameter("sign"));
  113. if ($this->getParameter('sign_type') == 'MD5') {
  114. return $this->getMD5Sign() == $swiftpassSign;
  115. } else if ($this->getParameter('sign_type') == 'RSA_1_1' || $this->getParameter('sign_type') == 'RSA_1_256') {
  116. return $this->verifyRSASign();
  117. }
  118. }
  119. function getMD5Sign() {
  120. $signPars = "";
  121. ksort($this->parameters);
  122. foreach($this->parameters as $k => $v) {
  123. if("sign" != $k && "" != $v) {
  124. $signPars .= $k . "=" . $v . "&";
  125. }
  126. }
  127. $signPars .= "key=" . $this->getKey();
  128. return strtolower(md5($signPars));
  129. }
  130. function verifyRSASign() {
  131. $signPars = "";
  132. ksort($this->parameters);
  133. foreach($this->parameters as $k => $v) {
  134. if("sign" != $k && "" != $v) {
  135. $signPars .= $k . "=" . $v . "&";
  136. }
  137. }
  138. $signPars = substr($signPars, 0, strlen($signPars) - 1);
  139. $res = openssl_get_publickey($this->public_rsa_key);
  140. if ($this->getParameter('sign_type') == 'RSA_1_1') {
  141. $result = (bool)openssl_verify($signPars, base64_decode($this->getParameter("sign")), $res);
  142. openssl_free_key($res);
  143. return $result;
  144. } else if($this->getParameter('sign_type') == 'RSA_1_256') {
  145. $result = (bool)openssl_verify($signPars, base64_decode($this->getParameter("sign")), $res, OPENSSL_ALGO_SHA256);
  146. openssl_free_key($res);
  147. return $result;
  148. }
  149. }
  150. /**
  151. *获取debug信息
  152. */
  153. function getDebugInfo() {
  154. return $this->debugInfo;
  155. }
  156. //获取xml编码
  157. function getXmlEncode($xml) {
  158. $ret = preg_match ("/<?xml[^>]* encoding=\"(.*)\"[^>]* ?>/i", $xml, $arr);
  159. if($ret) {
  160. return strtoupper ( $arr[1] );
  161. } else {
  162. return "";
  163. }
  164. }
  165. /**
  166. *设置debug信息
  167. */
  168. function _setDebugInfo($debugInfo) {
  169. $this->debugInfo = $debugInfo;
  170. }
  171. /**
  172. * 是否财付通签名
  173. * @param signParameterArray 签名的参数数组
  174. * @return boolean
  175. */
  176. function _isTenpaySign($signParameterArray) {
  177. $signPars = "";
  178. foreach($signParameterArray as $k) {
  179. $v = $this->getParameter($k);
  180. if("sign" != $k && "" != $v) {
  181. $signPars .= $k . "=" . $v . "&";
  182. }
  183. }
  184. $signPars .= "key=" . $this->getKey();
  185. $sign = strtolower(md5($signPars));
  186. $tenpaySign = strtolower($this->getParameter("sign"));
  187. //debug信息
  188. $this->_setDebugInfo($signPars . " => sign:" . $sign .
  189. " tenpaySign:" . $this->getParameter("sign"));
  190. return $sign == $tenpaySign;
  191. }
  192. }
  193. ?>