Files
docs/thinkphp/app/service/Signature.php
cenzuhai 3a04eede84 feat: 初始化进销存数据开放平台项目
初始化完整的前后端项目结构,包含ThinkPHP后端API服务和Next.js前端管理系统,添加基础配置、中间件、模型、路由等核心代码,以及项目文档和静态资源。
2026-07-08 17:48:00 +08:00

108 lines
2.7 KiB
PHP

<?php
namespace app\service;
/**
* 签名验证服务
* 完全按照 Python 版本实现
*/
class Signature
{
/**
* 生成API Key
*/
public static function generateApiKey()
{
return bin2hex(random_bytes(6));
}
/**
* 生成API Secret
*/
public static function generateApiSecret()
{
return bin2hex(random_bytes(10));
}
/**
* 对 API Secret 做 SHA256 哈希存储
*/
public static function hashSecret($secret)
{
return hash('sha256', $secret);
}
/**
* 验证签名(完全按照 Python 版本实现)
*
* @param array $params 请求查询参数
* @param string $timestamp X-Timestamp header 值
* @param string $signature X-Sign header 值
* @param string $apiSecretHash 数据库存储的 secret 哈希
* @return bool
*/
public static function verify($params, $timestamp, $signature, $apiSecretHash)
{
try {
$ts = (int)$timestamp;
if ($ts > 1e12) {
$ts = (int)($ts / 1000);
}
$now = time();
$expireSeconds = env('signature.expire_seconds', 300);
if (abs($now - $ts) > $expireSeconds) {
return false;
}
} catch (\Exception $e) {
return false;
}
$sortedParams = [];
foreach ($params as $k => $v) {
$sortedParams[$k] = $v;
}
ksort($sortedParams);
$paramParts = [];
foreach ($sortedParams as $k => $v) {
if ($v !== null && $v !== '') {
$paramParts[] = "{$k}={$v}";
}
}
$paramStr = implode('&', $paramParts);
$fullStr = $paramStr . '&timestamp=' . $timestamp;
$expectedSign = hash_hmac('sha256', $fullStr, $apiSecretHash);
return strcasecmp($expectedSign, $signature) === 0;
}
/**
* 生成签名(用于测试)
*
* @param array $params 请求参数
* @param string $timestamp 时间戳字符串
* @param string $apiSecret API Secret 明文
* @return string
*/
public static function sign($params, $timestamp, $apiSecret)
{
$sortedParams = [];
foreach ($params as $k => $v) {
$sortedParams[$k] = $v;
}
ksort($sortedParams);
$paramParts = [];
foreach ($sortedParams as $k => $v) {
if ($v !== null && $v !== '') {
$paramParts[] = "{$k}={$v}";
}
}
$paramStr = implode('&', $paramParts);
$fullStr = $paramStr . '&timestamp=' . $timestamp;
return hash_hmac('sha256', $fullStr, $apiSecret);
}
}