SignContentExtractor.php 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. <?php
  2. namespace Alipay\EasySDK\Kernel\Util;
  3. use Alipay\EasySDK\Kernel\AlipayConstants;
  4. class SignContentExtractor
  5. {
  6. private $RESPONSE_SUFFIX = "_response";
  7. private $ERROR_RESPONSE = "error_response";
  8. /**
  9. * @param $body string 网关的整体响应字符串
  10. * @param $method string 本次调用的OpenAPI接口名称
  11. * @return false|string|null 待验签的原文
  12. */
  13. public function getSignSourceData($body, $method)
  14. {
  15. $rootNodeName = str_replace(".", "_", $method) . $this->RESPONSE_SUFFIX;
  16. $rootIndex = strpos($body, $rootNodeName);
  17. if ($rootIndex !== strrpos($body, $rootNodeName)) {
  18. throw new \Exception('检测到响应报文中有重复的' . $rootNodeName . ',验签失败。');
  19. }
  20. $errorIndex = strpos($body, $this->ERROR_RESPONSE);
  21. if ($rootIndex > 0) {
  22. return $this->parserJSONSource($body, $rootNodeName, $rootIndex);
  23. } else if ($errorIndex > 0) {
  24. return $this->parserJSONSource($body, $this->ERROR_RESPONSE, $errorIndex);
  25. } else {
  26. return null;
  27. }
  28. }
  29. /**
  30. *
  31. * @param $responseContent
  32. * @param $nodeName
  33. * @param $nodeIndex
  34. * @return false|string|null
  35. */
  36. function parserJSONSource($responseContent, $nodeName, $nodeIndex)
  37. {
  38. $signDataStartIndex = $nodeIndex + strlen($nodeName) + 2;
  39. if (strrpos($responseContent, AlipayConstants::ALIPAY_CERT_SN_FIELD)) {
  40. $signIndex = strrpos($responseContent, "\"" . AlipayConstants::ALIPAY_CERT_SN_FIELD . "\"");
  41. } else {
  42. $signIndex = strrpos($responseContent, "\"" . AlipayConstants::SIGN_FIELD . "\"");
  43. }
  44. // 签名前-逗号
  45. $signDataEndIndex = $signIndex - 1;
  46. $indexLen = $signDataEndIndex - $signDataStartIndex;
  47. if ($indexLen < 0) {
  48. return null;
  49. }
  50. return substr($responseContent, $signDataStartIndex, $indexLen);
  51. }
  52. }