You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.9 KiB
PHP
125 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace app\common\service;
|
|
|
|
class SecureService
|
|
{
|
|
private $appId;
|
|
private $cid;
|
|
private $openid;
|
|
private $secret;
|
|
private $version;
|
|
private $device;
|
|
private $platform;
|
|
|
|
public function __construct($appId, $cid, $openid, $secret, $version, $device = "ios_1.0.0", $platform = "app")
|
|
{
|
|
$this->appId = $appId;
|
|
$this->cid = $cid;
|
|
$this->openid = $openid;
|
|
$this->secret = $secret;
|
|
$this->version = $version;
|
|
$this->device = $device;
|
|
$this->platform = $platform;
|
|
}
|
|
|
|
public function decrypt($json)
|
|
{
|
|
if (isset($json['crypto']) && strlen($json['crypto']) > 0) {
|
|
$ALGORITHM = 'aes-256-cbc';
|
|
$CIPHER_KEY = hex2bin($json['crypto']);
|
|
$cipherText = hex2bin($json['data']);
|
|
|
|
// 由于AES-256-CBC需要一个16字节的初始化向量(IV),我们需要从密文中提取它
|
|
$ivSize = openssl_cipher_iv_length($ALGORITHM);
|
|
$iv = substr($cipherText, 0, $ivSize);
|
|
$textBytes = substr($cipherText, $ivSize);
|
|
|
|
// 创建一个解密器
|
|
$decrypted = openssl_decrypt($textBytes, $ALGORITHM, $CIPHER_KEY, OPENSSL_RAW_DATA, $iv);
|
|
|
|
// 检查是否解密成功
|
|
if ($decrypted === false) {
|
|
throw new \Exception("Decryption failed: " . openssl_error_string());
|
|
}
|
|
|
|
// 将解密后的数据转换为JSON对象
|
|
$json['data'] = json_decode($decrypted, true);
|
|
}
|
|
return $json;
|
|
}
|
|
|
|
// 检查Base64编码
|
|
public function checkBase64($data)
|
|
{
|
|
try {
|
|
$decoded = base64_decode($data);
|
|
return json_decode($decoded, true);
|
|
} catch (\Exception $e) {
|
|
return $data;
|
|
}
|
|
}
|
|
|
|
// 获取签名后的地址
|
|
public function getSign($url)
|
|
{
|
|
// JS:appid=daodao&cid=1&crypto=2&device=ios_1.0.0&nonce_str=RN4FYwkp&nonce_time=1711590243&
|
|
// openid=&platform=app&version=v1.0.1&sign=C075C4F943DB9636798041EC23A58491
|
|
|
|
// $queryParams = array(
|
|
// 'appid' => 'daodao',
|
|
// 'cid' => 1,
|
|
// 'crypto' => 2,
|
|
// 'openid' => '',
|
|
// 'version' => 'v1.0.1',
|
|
// 'device' => 'ios_1.0.0',
|
|
// 'platform' => 'app',
|
|
// 'nonce_str' => 'RN4FYwkp',
|
|
// 'nonce_time' => '1711590243'
|
|
// );
|
|
$queryParams = array(
|
|
'appid' => $this->appId,
|
|
'cid' => $this->cid,
|
|
'openid' => $this->openid,
|
|
'version' => $this->version,
|
|
'device' => $this->device,
|
|
'platform' => $this->platform,
|
|
'nonce_str' => $this->_generateNonceString(8),
|
|
'nonce_time' => $this->_generateNonceDateline()
|
|
);
|
|
|
|
ksort($queryParams);
|
|
$params = http_build_query($queryParams);
|
|
$urlInfo = parse_url($url);
|
|
$pathAndQuery = isset($urlInfo['path']) ? $urlInfo['path'] : '';
|
|
|
|
$signString = $params . '&key=' . $this->secret;
|
|
$sign = strtoupper(md5($signString));
|
|
$params .= "&sign={$sign}";
|
|
|
|
return $urlInfo['scheme'] . '://' . $urlInfo['host'] . $pathAndQuery . '?' . $params;
|
|
}
|
|
|
|
// 生成时间戳
|
|
private function _generateNonceDateline()
|
|
{
|
|
return time();
|
|
}
|
|
|
|
// 生成随机字符串
|
|
private function _generateNonceString($length)
|
|
{
|
|
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
$maxPos = strlen($chars);
|
|
$nonceStr = "";
|
|
for ($i = 0; $i < $length; $i++) {
|
|
$nonceStr .= $chars[mt_rand(0, $maxPos - 1)];
|
|
}
|
|
return $nonceStr;
|
|
}
|
|
}
|
|
|
|
// 使用示例
|
|
// $secure = new Secure('your_app_id', 'your_cid', 'your_openid', 'your_secret', 'your_version');
|
|
// $signedUrl = $secure->getSign('https://example.com', array('param1' => 'value1', 'param2' => 'value2'));
|
|
// echo $signedUrl;
|