Test.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. namespace app\api\controller;
  3. use think\Config;
  4. use think\Env;
  5. use think\Exception;
  6. class Test extends Api
  7. {
  8. public function _initialize(){
  9. // parent::_initialize();
  10. }
  11. public function index(){
  12. // http://sdkapi.newsdk.com/test/index
  13. // ## 客户端加密
  14. // $data = [
  15. // "appid" => "xxxx",
  16. // "channel_id" => "xxxx",
  17. // "device" => "xxxx",
  18. // "gameid" => "xxxx",
  19. // "imeil" => "17322362573792438064",
  20. // "version" => "v3.4.0",
  21. // ];
  22. // // $str = $this->handleEncrypt($data, 'h5');
  23. //
  24. // $data = '{"username":"13121776520","password":"123456","token":"{{token}}","device":4,"channel_id":5215,"imeil":"00000000-1645-d5b5-ffff-ffffef05ac4a-wen","version":"v3.4.4","client_appkey":"dda26b4dab356247eb84193fe51baa97","aes_key":"qmQWERBABA202308","aes_key_h5":"qmQWERBABA20241210","appid":30,"gameid":30}';
  25. // $str = openssl_encrypt($data, 'AES-128-ECB', 'qmQWERBABA20241210');
  26. // var_dump($str);
  27. // // $str = 'hyvW9z17k/Gz1Ja2ghqw6YcFrvbAqT57xl2/kj3L8k35G8gB2kBxYKW2TZ7u+riaWjxcQ/0mvNqQQ0rPd+KQuUC/a8CQatA602Dy4FGVS3UKHTX+GlUa2DBGY+wDr/jPw6l3EYbbnjH9U5yXTQa4fmOptFo87WDNkhlIQuAZeEo=';
  28. // $str = 'msVNNwhwHMAs8wiDo5Y6pw2+R//+8NcWC34E94YmlrenPY++V1pQa4QIBOZfh3PyviREDG09vmxyKN+jvxrGUw1s6rVPuB9sy/oo2XrnyPt5nRHL2rk0scMofF9U8Ani0EFXJ2tbttcRKB5dcfG2yaP2BdWWV27xWEiX+0KXXdU=';
  29. // // $str = '9fU3EmTnXKV7a84pnRVopcapXDYvNwkR1orMUE2Kcka+vGT31AuvfM0E7mDDIp9/x2Q89cobiFdBmV1SO557Sa/5eShMosFcd73nMTG9rIPWh/2g51rsPD8Uv7QQftTr';
  30. // // $res = $this->opensslDecrypt($str, Config::get('aes_key_h5'));
  31. // $res = $this->opensslDecrypt($str, 'qmQWERBABA202308'); // app
  32. // // $res = $this->opensslDecrypt($str, 'qmQWERBABA202412'); // h5
  33. //
  34. // dump(Config::get('aes_key_h5'), $str, $res, json_decode($res));
  35. try {
  36. // $param = [
  37. // "app_id" => 'ks684828619578671316',
  38. // "channel_id" => 'ks',
  39. // "game_id" => '120592009db298fe1307fb38a3cdf83acb',
  40. // "role_id" => 'xxxx',
  41. // "role_name" => 'xxx',
  42. // "role_level" => 'xxx',
  43. // "server_id" => 'xxx',
  44. // "server_name" => 'xxx',
  45. // "product_id" => 'xxx',
  46. // "product_name" => 'xxx',
  47. // "product_desc" => 'xxx',
  48. // "money" => formatYuanToFen(1),
  49. // "currency_type" => 'CNY',
  50. // "notify_url" => 'xxx',
  51. // "extension" => json_encode(['order_id' => 'xxx']),
  52. // "user_ip" => 'xxx',
  53. // "third_party_trade_no" => 'xxx',
  54. // ];
  55. // $sign = $this->handleQm($param, $this->getKeyData('pay'));
  56. // dump($sign);
  57. $param = input();
  58. $sign = input('sign');
  59. dump($param);
  60. $sign = $this->handleSignVerify($param, $this->getKeyData('notify'), $sign);
  61. dump('## sign: ', $sign);
  62. }catch (Exception $e){
  63. dump("ERROR: ", $e->getMessage());
  64. }
  65. }
  66. /**
  67. * 获取签名秘钥
  68. *
  69. * @param $type 类型 pay|notify
  70. * @return string
  71. */
  72. public function getKeyData($type = 'pay')
  73. {
  74. $key_file = APP_PATH . 'common/config/complex/qm_private_key.pem';
  75. if ($type == 'notify') {
  76. $key_file = APP_PATH . 'common/config/complex/kuaishou_public.pem';
  77. // $key_file = APP_PATH . 'common/config/complex/qm_public_key.pem';
  78. // $key_file = APP_PATH . 'common/config/complex/qm_public_key.pem';
  79. }
  80. if (!file_exists($key_file)) {
  81. return '';
  82. }
  83. return file_get_contents($key_file);
  84. }
  85. /**
  86. * 处理签名数据
  87. *
  88. * @param $data
  89. *
  90. * @return string
  91. */
  92. public function handleSignData($data){
  93. ksort($data);
  94. $signString = '';
  95. foreach ($data as $key => $value) {
  96. if($key == 'sign'){
  97. continue;
  98. }
  99. if ($signString !== '') {
  100. $signString .= '&';
  101. }
  102. $signString .= $key . '=' . $value;
  103. }
  104. return $signString;
  105. }
  106. /**
  107. * 使用 RSA 私钥 + SHA512 签名数组
  108. *
  109. * @param array $data 要签名的数组
  110. * @param string $privateKey 私钥内容(PEM格式)
  111. * @return string Base64 编码签名字符串
  112. */
  113. function handleSign(array $data, string $privateKey): string
  114. {
  115. $signString = $this->handleSignData($data);
  116. $pkey = openssl_pkey_get_private($privateKey);
  117. if (!$pkey) {
  118. throw new Exception('无效的 RSA 私钥');
  119. }
  120. $signature = '';
  121. $success = openssl_sign($signString, $signature, $pkey, OPENSSL_ALGO_SHA512);
  122. openssl_free_key($pkey);
  123. if (!$success) {
  124. throw new Exception('签名失败');
  125. }
  126. // 6. 返回 Base64 编码后的签名
  127. return base64_encode($signature);
  128. }
  129. /**
  130. * 签名效验
  131. *
  132. * @param array $data
  133. * @param string $publicKey
  134. * @param string $signstr
  135. *
  136. * @return bool
  137. */
  138. function handleSignVerify(array $data, string $publicKey, string $signstr): string
  139. {
  140. $publicKey = <<<EOD
  141. -----BEGIN PUBLIC KEY-----
  142. MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8eW4XgoSoaBptOKjuLWY
  143. Dzec+jGeJEYLCMEnIqPIvr6M695mZDkiS4Q5eO+Ksdrh9aTTfqRkZ+BfjJaNrNT1
  144. MYfhHT3u75WHslIVa7iNz/9440OnAJ2U+eqLjDPTJzEojxvMw+3E5i205Y9DG53S
  145. 4YcRkutQ2akmtD7ujBi7/bsp5FpgDlER5IP2lUq0Qo6cH0ZQvwjrC3OR3M63YUDE
  146. yThJrNsdBGR5bKVg4LGgeI48V29YLhcc8p18MgqbrXULdAfe2zFnsJ16pOLuxnNJ
  147. OSvVPe7U5IPMKxSfiA0jYNn8r74efXQL1EPdG/3Og1R9h0EnZRCiFMpczwOYacEl
  148. ewIDAQAB
  149. -----END PUBLIC KEY-----
  150. EOD;
  151. // dump($publicKey, $public_key1);
  152. $signString = $this->handleSignData($data);
  153. $public_key_res = openssl_get_publickey($publicKey);
  154. $res = openssl_verify($signString, base64_decode($signstr), $public_key_res, OPENSSL_ALGO_SHA512);
  155. if($res == 1){
  156. return true;
  157. }
  158. return false;
  159. }
  160. }