tapi/app/Request.php
2025-08-29 16:18:02 +08:00

148 lines
3.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app;
// 应用请求对象类
use app\http\HttpAuth;
use app\http\HttpClient;
use think\exception\ValidateException;
use think\helper\Macroable;
/**
* @method static HttpClient getClient() 获取客户端信息
*/
class Request extends \think\Request
{
use Macroable;
/**
* @var string
*/
public string $contextId = '';
/**
* @var HttpAuth
*/
private readonly HttpAuth $auth;
/**
* 设置Auth
* @param HttpAuth $auth
* @return Request
*/
public function setAuth(HttpAuth $auth): self
{
$this->auth = $auth;
return $this;
}
public function getAuth(): ?HttpAuth
{
// var_dump($this->auth);
return $this->auth ?? null;
}
public function getBrowser(): string
{
return get_agent_browser($this->server('HTTP_USER_AGENT'));
}
public function getDevice(): string
{
return get_agent_device($this->server('HTTP_USER_AGENT'));
}
public function getOs(): string
{
return get_agent_os($this->server('HTTP_USER_AGENT'));
}
const string DATA_SECRET_KEY = "mySecretKey123!";
/**
* 加密数据
*/
static function encryptCryptoJSAES($data): string
{
// 如果是数组或对象,转换为 JSON 字符串
if (is_array($data) || is_object($data)) {
$data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
// 生成随机 salt (8字节)
$salt = openssl_random_pseudo_bytes(8);
// 通过 EVP_BytesToKey 派生密钥和 IV
$keyIv = self::evpBytesToKey($salt);
$key = $keyIv['key'];
$iv = $keyIv['iv'];
// // 添加 PKCS#7 填充
// $blockSize = 16; // AES 块大小
// $padding = $blockSize - (strlen($data) % $blockSize);
// $data .= str_repeat(chr($padding), $padding);
// AES-256-CBC 加密
$encrypted = openssl_encrypt(
$data,
'aes-256-cbc',
$key,
OPENSSL_RAW_DATA,
$iv
);
// 组合 Salted__ + salt + 加密数据
$result = "Salted__" . $salt . $encrypted;
// Base64 编码
return base64_encode($result);
}
/**
* 解密 CryptoJS 加密的数据
*/
static function decryptCryptoJSData(string $encryptedData): string
{
// Base64解码
$data = base64_decode($encryptedData);
// 检查Salted__头
if (!str_starts_with($data, "Salted__")) {
throw new ValidateException('Invalid format: missing "Salted__" header');
}
// 提取Salt (8字节)
$salt = substr($data, 8, 8);
$ct = substr($data, 16);
// 通过EVP_BytesToKey派生密钥和IV
$keyIv = self::evpBytesToKey($salt);
$key = $keyIv['key'];
$iv = $keyIv['iv'];
// AES-256-CBC解密
return openssl_decrypt(
$ct,
'aes-256-cbc',
$key,
OPENSSL_RAW_DATA,
$iv
);
}
static private function evpBytesToKey($salt): array
{
$password = self::DATA_SECRET_KEY;
$bytes = '';
$last = '';
// 生成48字节32字节key + 16字节IV
while(strlen($bytes) < 48) {
$last = md5($last . $password . $salt, true);
$bytes .= $last;
}
return [
'key' => substr($bytes, 0, 32),
'iv' => substr($bytes, 32, 16)
];
}
}