diff --git a/CHANGELOG.md b/CHANGELOG.md index 7efeb56a05e3cb1360494661b9fa6cfd5d8a0975..1050ed6cec8ea5132fcfffe7c133c712b7ab3df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -## v6.0.83 / 2020-07-13 (未发布,开发版可以体验) -- 修复标准Api控制器基类签名编码问题 +## v6.0.83 / 2020-07-16 +- 通知签名规则和加密方法,使用aes方式 +- 更新IP数据库 ## v6.0.82 / 2020-07-13 - 优化标准Api控制器基类 diff --git a/src/ApiController.php b/src/ApiController.php index cbc68342c12bc3eb7ac07c04bd52a2f1705715e1..49d51d248cead94ddb86f253a5f07d8b2facfff0 100644 --- a/src/ApiController.php +++ b/src/ApiController.php @@ -43,6 +43,12 @@ class ApiController extends stdClass */ public $request; + /** + * 解密后数据 + * @var + */ + private $aes_decrypt_data; + /** * ApiController constructor. * @param App $app @@ -91,6 +97,23 @@ class ApiController extends stdClass ])); } + /** + * 返回成功的操作 + * @param mixed $msg 消息内容 + * @param mixed $data 返回数据 + * @param integer $code 返回代码 + */ + public function aesSuccess($data = [], $msg = 'success', $code = 0, $name = 'sniff_h5') + { + if ($data === []) $data = new stdClass(); + $timestamp = time(); + throw new HttpResponseException(json([ + 'code' => $code, 'msg' => $msg, 'timestamp' => $timestamp, 'data' => [ + 'aes' => $this->encrypt($data, $name, $timestamp) + ], + ])); + } + /** * URL重定向 * @param string $url 跳转链接 @@ -115,80 +138,89 @@ class ApiController extends stdClass return true; } + /** + * 获取解密后的数据 + * @param string $name + * @param null $default + * @return mixed + */ + public function getAesDecryptData(string $name, $default = null) + { + if (isset($this->aes_decrypt_data[$name])) { + return $this->aes_decrypt_data[$name]; + } else return $default; + } /** * 验证接口签名 - * @param $name - * @return string + * @param string $name */ - public function _judgeSign($name) + public function _judgeSign($name = 'sniff_h5') { - if (empty(request()->header('sign', ''))) $this->error('数据未签名!', 666); - // 全部参数 - $arr = request()->post(); - $timestamp = request()->get('timestamp', 0); + if (empty($this->request->header('sign', ''))) $this->error('数据未签名!', 104); + + // 加密的数据参数 + $aes = $this->request->post('aes'); + // 获取时间数据 + $timestamp = $this->request->get('timestamp', 0); + // 判断是否有时间 - if (empty($timestamp)) $this->error('数据异常!', 666); - $arr['timestamp'] = $timestamp; - // 删除sign - foreach ($arr as $k => $v) if ('sign' == $k) unset($arr[$k]); - // 排序 - $arr = $this->argSort($arr, $name); + if (empty($timestamp)) $this->error('数据异常!', 105); + + // 解密 + $aes_decode = $this->decrypt($aes, $name, $timestamp); + if (empty($aes_decode)) $this->error('解密失败', 106); + $data = json_decode($aes_decode, true); + + // 服务器加密 + $encrypt = $this->encrypt($data, $name, $timestamp); + + // 服务器签名 + $sign = $this->md5Sign($encrypt); + // 服务器签名对比 - $sign = $this->md5Sign($arr); - if ($sign != request()->header('sign', '')) $this->error('验证不匹配!', 666); + if ($sign != $this->request->header('sign', '')) $this->error('验证不匹配!', 107); + // 判断是不是小于服务器时间 $before = strtotime('-2minute'); $rear = strtotime('+2minute'); - if ($timestamp <= $rear && $timestamp >= $before) return true; + if ($timestamp <= $rear && $timestamp >= $before) $this->aes_decrypt_data = $data; else $this->error('已超时,请重新尝试!'); } /** - * 对数组排序 - * @param $param - * @param string $name - * @return mixed 排序后的数组 + * 生成md5签名字符串 + * @param $preStr string 需要签名的字符串 + * @return string 签名结果 */ - private function argSort($param, $name) + private function md5Sign(string $preStr) { - ksort($param); - return $this->createLinkString($param, $name); + return strtoupper(md5($preStr)); } - /** - * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 - * @param $para - * @param string $name - * @return bool|string 拼接完成以后的字符串 - */ - private function createLinkString(array $para, string $name) - { - $string = $this->toParams($para);// 将数组转换成字符串 - $string = $string . '&key=' . config("dtapp.md5.{$name}"); - return $string; - } /** - * 生成md5签名字符串 - * @param $preStr string 需要签名的字符串 - * @return string 签名结果 + * 加密 + * @param $data + * @param string $name + * @param int $timestamp + * @return bool|string */ - private function md5Sign(string $preStr) + public function encrypt($data, string $name, int $timestamp) { - return strtoupper(md5($preStr)); + if (!empty(is_array($data))) $data = json_encode($data); + return urlencode(base64_encode(openssl_encrypt($data, 'AES-128-CBC', config("dtapp.md5.{$name}"), 1, config("dtapp.md5.bcw") . $timestamp))); } /** - * 格式化参数格式化成url参数 - * @param array $data - * @return string + * 解密 + * @param string $data + * @param string $name + * @param int $timestamp + * @return bool|false|string */ - private function toParams(array $data) + private function decrypt(string $data, string $name, int $timestamp) { - $buff = ""; - foreach ($data as $k => $v) if ($k != "sign" && $v !== "" && !is_array($v)) $buff .= $k . "=" . urlencode($v) . "&"; - $buff = trim($buff, "&"); - return $buff; + return openssl_decrypt(base64_decode(urldecode($data)), "AES-128-CBC", config("dtapp.md5.{$name}"), true, config("dtapp.md5.bcw") . $timestamp); } } diff --git a/src/service/bin/qqwry.dat b/src/service/bin/qqwry.dat index 375a407ee3e337be1c665531fcef499082ff69a4..c864fce9ff6896512fbfa9f4b76ae87e517c9e0f 100644 Binary files a/src/service/bin/qqwry.dat and b/src/service/bin/qqwry.dat differ