PaySign.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace addons\Sicpay\common\sdk;
  3. /**
  4. * 一户一码
  5. */
  6. class PaySign{
  7. public function sendEncodeData($json, $config){
  8. unset($json['merRsaPrivateKey'],$json['rootRsaPublicKey']);
  9. // echo "<pre>";
  10. // var_dump($json);
  11. $json_content = json_encode($json);
  12. //随机生成aes密钥
  13. $aes_key = $this->randomKeys(16);
  14. //商户RSA私钥
  15. if( empty($config['merRsaPrivateKey']) ){
  16. $private_rsa_key = file_get_contents($this->getPath() . $config['agencyId'] . '/' . $config['agencyId']. '.pem');
  17. }else{
  18. $private_rsa_key = $config['merRsaPrivateKey'];
  19. }
  20. //我司平台RSA公钥
  21. if( empty($config['rootRsaPublicKey']) ){
  22. $public_rsa_key = file_get_contents($this->getPath() . $config['agencyId'] . '/' . 'GHT_ROOT.pem');
  23. }else{
  24. $public_rsa_key = $config['rootRsaPublicKey'];
  25. }
  26. //用上面随机生成的aes密钥加密请求报文
  27. $data['encryptData'] = $this->aesEncode($json_content, $aes_key);
  28. //用我司平台rsa公钥加密上面随机生成的aes密钥
  29. $data['encryptKey'] = $this->rsaEncode($aes_key, $public_rsa_key);
  30. //用商户ras私钥签名
  31. $data['signData'] = $this->rsaSign($json_content, $private_rsa_key);
  32. $data['agencyId'] = $config['agencyId'];
  33. $data_content = json_encode($data);
  34. //发送请求
  35. $request_result = $this->httpPost($data_content, $config['url']);
  36. // var_dump($request_result);exit;
  37. //解密返回报文
  38. $result_json = json_decode($request_result,true);
  39. //用商户私钥解密aes密钥(是由平台随机生成的)
  40. $result_aes_key = $this->rsaDecode($result_json['encryptKey'], $private_rsa_key);
  41. //用aes密钥解密报文
  42. $decode_content = $this->aesDecode($result_json['encryptData'],$result_aes_key);
  43. // var_dump($decode_content);exit;
  44. //用平台公钥验签
  45. if($this->verifySign($decode_content, $result_json['signData'], $public_rsa_key)){
  46. $res = json_decode($decode_content,true);
  47. // var_dump($res);exit;
  48. return $res;
  49. } else {
  50. //验签失败
  51. throw new \Exception("SICPAY 验签失败");
  52. }
  53. }
  54. private function aesEncode($data, $aes_key){
  55. $encrypt_data = openssl_encrypt($this->pad($data), "aes-128-ecb", $aes_key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
  56. return base64_encode($encrypt_data);
  57. }
  58. public function aesDecode($data,$aes_key){
  59. $data = base64_decode($data);
  60. return openssl_decrypt($data, "aes-128-ecb", $aes_key, OPENSSL_RAW_DATA);
  61. }
  62. private function rsaEncode($data, $public_rsa_key){
  63. $ret = false;
  64. // if (!self::_checkPadding(OPENSSL_PKCS1_PADDING, 'en')){
  65. // return 'padding error';
  66. // }
  67. $key = openssl_get_publickey($public_rsa_key);
  68. if (openssl_public_encrypt($data,$result,$key,OPENSSL_PKCS1_PADDING)){
  69. $ret = base64_encode($result);
  70. }
  71. return $ret;
  72. }
  73. private function rsaDecode($data, $private_rsa_key){
  74. $ret = false;
  75. $data = base64_decode($data);
  76. if ($data !== false){
  77. if (openssl_private_decrypt($data, $result, $private_rsa_key, OPENSSL_PKCS1_PADDING)){
  78. $ret = $result;
  79. }
  80. }
  81. return $ret;
  82. }
  83. private function rsaSign($data, $private_rsa_key) {
  84. $res = openssl_get_privatekey ($private_rsa_key);
  85. openssl_sign($data,$sign, $res);
  86. openssl_free_key($res);
  87. $sign = base64_encode($sign);
  88. return $sign;
  89. }
  90. private function verifySign($data, $signData, $public_rsa_key){
  91. $signData =base64_decode($signData);
  92. $res = openssl_get_publickey($public_rsa_key);
  93. $result = openssl_verify($data, $signData, $res);
  94. openssl_free_key($res);
  95. if($result === 1){
  96. return true;
  97. } else {
  98. return false;
  99. }
  100. }
  101. private function httpPost($data,$url){
  102. $ch = curl_init();
  103. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
  104. curl_setopt($ch,CURLOPT_TIMEOUT,600);
  105. curl_setopt($ch,CURLOPT_URL,$url);
  106. curl_setopt($ch,CURLOPT_POST,true);
  107. curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
  108. curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
  109. if (strpos($url, 'https') !== false) {
  110. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  111. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
  112. curl_setopt($ch, CURLOPT_SSLVERSION, 1);
  113. }
  114. $ret_data = trim(curl_exec($ch));
  115. curl_close($ch);
  116. return $ret_data;
  117. }
  118. //获取当前绝对路径
  119. private function getPath(){
  120. return dirname(__FILE__).'/';
  121. }
  122. private function randomKeys($length)
  123. {
  124. $key = '';
  125. $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ';
  126. for($i=0;$i<$length;$i++) {
  127. $key .= $pattern[mt_rand(0,35)]; //生成php随机数
  128. }
  129. return $key;
  130. }
  131. private function pad($data, $blocksize = 16) {
  132. $pad = $blocksize - (strlen($data) % $blocksize);
  133. return $data . str_repeat(chr($pad), $pad);
  134. }
  135. // 异步解压
  136. //1. 将encryptKey做base64解密,然后使⽤merRsaPrivateKey进⾏RSA解密,得到rootAesKey
  137. //2. 将encryptData做base64解密,然后使⽤rootAesKey进⾏AES解密,得到业务报⽂
  138. //3. 将signData做base64解密,然后与rootRsaPublicKey、业务报⽂共同进⾏SHA1WithRSA验签
  139. public function notifyDecodeData($config,$result_json){
  140. //用商户私钥解密aes密钥(是由平台随机生成的)
  141. $result_aes_key = $this->rsaDecode($result_json['encryptKey'], $config['merRsaPrivateKey']);
  142. //用aes密钥解密报文
  143. $decode_content = $this->aesDecode($result_json['encryptData'],$result_aes_key);
  144. //用平台公钥验签
  145. if($this->verifySign($decode_content, $result_json['signData'], $config['rootRsaPublicKey'])){
  146. return json_decode($decode_content,true);
  147. } else {
  148. //验签失败
  149. throw new \Exception("SICPAY 验签失败");
  150. }
  151. }
  152. }