Test.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <?php
  2. namespace app\api\controller;
  3. use addons\fastchat\library\Chat;
  4. use alisdk\AliPay;
  5. use app\admin\model\system\GrantVoucher;
  6. use app\api\model\massager\Work;
  7. use app\api\model\order\Order;
  8. use app\api\service\BDService;
  9. use app\api\service\CallbackService;
  10. use app\api\service\MassagerService;
  11. use app\api\service\ProfitService;
  12. use app\api\service\StoreService;
  13. use app\api\service\TencentCloudService;
  14. use app\api\service\WxService;
  15. use app\api\validate\BaseApiValidate;
  16. use app\common\controller\Api;
  17. use redis\RedLock;
  18. class Test extends Api
  19. {
  20. protected $noNeedLogin = ["*"];
  21. function test1() {
  22. $order = (new Order())->get(1387);
  23. $res = (new ProfitService())->profit($order, db("user")->where("id", $order["user_id"])->find());
  24. if($res->code()) {
  25. $this->success($res->msg());
  26. } else {
  27. $this->success($res->data());
  28. }
  29. }
  30. /**
  31. * 获取证书
  32. * @return mixed
  33. */
  34. public static function certificates(){
  35. //请求参数(报文主体)
  36. $headers = self::sign('GET','https://api.mch.weixin.qq.com/v3/certificates','');
  37. $result = self::curl_get('https://api.mch.weixin.qq.com/v3/certificates',$headers);
  38. $result = json_decode($result,true);
  39. $aa = self::decryptToString($result['data'][0]['encrypt_certificate']['associated_data'],$result['data'][0]['encrypt_certificate']['nonce'],$result['data'][0]['encrypt_certificate']['ciphertext']);
  40. var_dump($aa);//解密后的内容,就是证书内容
  41. }
  42. /**
  43. * 签名
  44. * @param string $http_method 请求方式GET|POST
  45. * @param string $url url
  46. * @param string $body 报文主体
  47. * @return array
  48. */
  49. public static function sign($http_method = 'POST',$url = '',$body = ''){
  50. $mch_private_key = self::getMchKey();//私钥
  51. $timestamp = time();//时间戳
  52. $nonce = self::getRandomStr(32);//随机串
  53. $url_parts = parse_url($url);
  54. $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
  55. //构造签名串
  56. $message = $http_method."\n".
  57. $canonical_url."\n".
  58. $timestamp."\n".
  59. $nonce."\n".
  60. $body."\n";//报文主体
  61. //计算签名值
  62. openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
  63. $sign = base64_encode($raw_sign);
  64. //设置HTTP头
  65. $config = self::config();
  66. $token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
  67. $config['mchid'], $nonce, $timestamp, $config['serial_no'], $sign);
  68. $headers = [
  69. 'Accept: application/json',
  70. 'User-Agent: */*',
  71. 'Content-Type: application/json; charset=utf-8',
  72. 'Authorization: '.$token,
  73. ];
  74. return $headers;
  75. }
  76. //私钥
  77. public static function getMchKey(){
  78. var_dump(file_get_contents("file:///www/wwwroot/pool_ball_baby_server/certificate/wx/apiclient_key.pem"));
  79. //path->私钥文件存放路径
  80. return openssl_get_privatekey(file_get_contents("file:///www/wwwroot/pool_ball_baby_server/certificate/wx/apiclient_key.pem"));
  81. }
  82. /**
  83. * 获得随机字符串
  84. * @param $len integer 需要的长度
  85. * @param $special bool 是否需要特殊符号
  86. * @return string 返回随机字符串
  87. */
  88. public static function getRandomStr($len, $special=false){
  89. $chars = array(
  90. "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
  91. "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
  92. "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
  93. "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
  94. "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
  95. "3", "4", "5", "6", "7", "8", "9"
  96. );
  97. if($special){
  98. $chars = array_merge($chars, array(
  99. "!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
  100. "%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
  101. "}", "<", ">", "~", "+", "=", ",", "."
  102. ));
  103. }
  104. $charsLen = count($chars) - 1;
  105. shuffle($chars); //打乱数组顺序
  106. $str = '';
  107. for($i=0; $i<$len; $i++){
  108. $str .= $chars[mt_rand(0, $charsLen)]; //随机取出一位
  109. }
  110. return $str;
  111. }
  112. /**
  113. * 配置
  114. */
  115. public static function config(){
  116. return [
  117. 'appid' => '',
  118. 'mchid' => '1651873606',//商户号
  119. 'serial_no' => '4C24C6C4B0F88FAB756AA175D720D87A32B6BF23',//证书序列号
  120. 'description' => '',//应用名称(随意)
  121. 'notify' => '',//支付回调
  122. ];
  123. }
  124. //get请求
  125. public static function curl_get($url,$headers=array())
  126. {
  127. $info = curl_init();
  128. curl_setopt($info,CURLOPT_RETURNTRANSFER,true);
  129. curl_setopt($info,CURLOPT_HEADER,0);
  130. curl_setopt($info,CURLOPT_NOBODY,0);
  131. curl_setopt($info,CURLOPT_SSL_VERIFYPEER,false);
  132. curl_setopt($info,CURLOPT_SSL_VERIFYPEER,false);
  133. curl_setopt($info,CURLOPT_SSL_VERIFYHOST,false);
  134. //设置header头
  135. curl_setopt($info, CURLOPT_HTTPHEADER,$headers);
  136. curl_setopt($info,CURLOPT_URL,$url);
  137. $output = curl_exec($info);
  138. curl_close($info);
  139. return $output;
  140. }
  141. const KEY_LENGTH_BYTE = 32;
  142. const AUTH_TAG_LENGTH_BYTE = 16;
  143. /**
  144. * Decrypt AEAD_AES_256_GCM ciphertext
  145. *
  146. * @param string $associatedData AES GCM additional authentication data
  147. * @param string $nonceStr AES GCM nonce
  148. * @param string $ciphertext AES GCM cipher text
  149. *
  150. * @return string|bool Decrypted string on success or FALSE on failure
  151. */
  152. public static function decryptToString($associatedData, $nonceStr, $ciphertext) {
  153. $aesKey = '8b70e85dd34b80b2e519eacd7a1abfd8';
  154. $ciphertext = \base64_decode($ciphertext);
  155. if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {
  156. return false;
  157. }
  158. // ext-sodium (default installed on >= PHP 7.2)
  159. if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
  160. return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
  161. }
  162. // ext-libsodium (need install libsodium-php 1.x via pecl)
  163. if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) {
  164. return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
  165. }
  166. // openssl (PHP >= 7.1 support AEAD)
  167. if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
  168. $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
  169. $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);
  170. return \openssl_decrypt($ctext, 'aes-256-gcm', $aesKey, \OPENSSL_RAW_DATA, $nonceStr,
  171. $authTag, $associatedData);
  172. }
  173. throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
  174. }
  175. }