sdkappid = $sdkappid; $this->key = $key; } /** * 生成UserSig * @param string $identifier 用户ID * @param int $expire 过期时间(秒) * @return string UserSig */ public function genUserSig($identifier, $expire = 86400) { return $this->__genSig($identifier, $expire, '', false); } /** * 生成带权限的UserSig * @param string $identifier 用户ID * @param int $expire 过期时间(秒) * @param string $userbuf 用户权限buffer * @return string UserSig */ public function genUserSigWithUserBuf($identifier, $expire, $userbuf) { return $this->__genSig($identifier, $expire, $userbuf, true); } /** * 内部方法:生成签名 */ private function __genSig($identifier, $expire, $userbuf, $userbuf_enabled) { $current = time(); $sigDoc = [ 'TLS.ver' => '2.0', 'TLS.identifier' => strval($identifier), 'TLS.sdkappid' => intval($this->sdkappid), 'TLS.expire' => intval($expire), 'TLS.time' => intval($current) ]; $base64_userbuf = ''; if ($userbuf_enabled) { $base64_userbuf = base64_encode($userbuf); $sigDoc['TLS.userbuf'] = $base64_userbuf; } $sig = $this->hmacsha256($identifier, $current, $expire, $base64_userbuf, $userbuf_enabled); $sigDoc['TLS.sig'] = base64_encode($sig); $json_text = json_encode($sigDoc); $compressed = gzcompress($json_text); return $this->base64_url_encode($compressed); } /** * 生成HMAC-SHA256签名 */ private function hmacsha256($identifier, $curr_time, $expire, $base64_userbuf, $userbuf_enabled) { $content_to_be_signed = "TLS.identifier:" . $identifier . "\n" . "TLS.sdkappid:" . $this->sdkappid . "\n" . "TLS.time:" . $curr_time . "\n" . "TLS.expire:" . $expire . "\n"; if ($userbuf_enabled) { $content_to_be_signed .= "TLS.userbuf:" . $base64_userbuf . "\n"; } return hash_hmac('sha256', $content_to_be_signed, $this->key, true); } /** * Base64 URL安全编码 */ private function base64_url_encode($input) { return str_replace(['+', '/', '='], ['*', '-', '_'], base64_encode($input)); } /** * Base64 URL安全解码 */ private function base64_url_decode($base64_url_string) { return base64_decode(str_replace(['*', '-', '_'], ['+', '/', '='], $base64_url_string)); } /** * 验证UserSig * @param string $sig UserSig * @param string $identifier 用户ID * @param int $init_time 初始化时间 * @param int $expire_time 过期时间 * @param string $userbuf 用户权限buffer * @param string $error_msg 错误信息 * @return bool 是否有效 */ public function verifySig($sig, $identifier, &$init_time, &$expire_time, &$userbuf, &$error_msg) { try { $error_msg = ''; $compressed_sig = $this->base64_url_decode($sig); $pre_level = error_reporting(E_ERROR); $uncompressed_sig = gzuncompress($compressed_sig); error_reporting($pre_level); if ($uncompressed_sig === false) { throw new \Exception('gzuncompress error'); } $sig_doc = json_decode($uncompressed_sig, true); if ($sig_doc === false) { throw new \Exception('json_decode error'); } if ($sig_doc['TLS.identifier'] !== $identifier) { throw new \Exception('identifier dosen\'t match'); } if ($sig_doc['TLS.sdkappid'] != $this->sdkappid) { throw new \Exception('sdkappid dosen\'t match'); } $sig = base64_decode($sig_doc['TLS.sig']); if ($sig === false) { throw new \Exception('sig base64_decode error'); } $init_time = $sig_doc['TLS.time']; $expire_time = $sig_doc['TLS.expire']; $curr_time = time(); if ($curr_time > $init_time + $expire_time) { throw new \Exception('sig expired'); } $userbuf_enabled = false; $base64_userbuf = ''; if (isset($sig_doc['TLS.userbuf'])) { $base64_userbuf = $sig_doc['TLS.userbuf']; $userbuf = base64_decode($base64_userbuf); $userbuf_enabled = true; } $sigCalculated = $this->hmacsha256($identifier, $init_time, $expire_time, $base64_userbuf, $userbuf_enabled); if ($sig != $sigCalculated) { throw new \Exception('verify failed'); } return true; } catch (\Exception $ex) { $error_msg = $ex->getMessage(); return false; } } }