diff --git a/functions.php b/functions.php
index 4802dd85..905d8ecc 100644
--- a/functions.php
+++ b/functions.php
@@ -2305,19 +2305,17 @@ function change_avatar($avatar)
preg_match('/:\"([^\"]*)\"/i', $qqavatar, $matches);
return '
';
}
-
+
// Ensure $sakura_privkey is defined and not null
if (isset($sakura_privkey) && !is_null($sakura_privkey)) {
- // 生成一个合适长度的初始化向量
- $iv_length = openssl_cipher_iv_length('aes-128-cbc');
- $iv = openssl_random_pseudo_bytes($iv_length);
-
+ $iv = substr(md5($sakura_privkey), 0, 16);
+
// 加密数据
$encrypted = openssl_encrypt($qq_number, 'aes-128-cbc', $sakura_privkey, 0, $iv);
-
+
// 将初始化向量和加密数据一起编码
$encrypted = urlencode(base64_encode($iv . $encrypted));
-
+
return '
';
} else {
// Handle the case where $sakura_privkey is not set or is null
@@ -2326,7 +2324,6 @@ function change_avatar($avatar)
}
return $avatar;
}
-
//生成随机链接,防止浏览器缓存策略
function get_random_url(string $url): string
{
@@ -4212,3 +4209,20 @@ function iro_action_operator()
}
}
iro_action_operator();
+
+
+/* * 检查并生成加密密钥
+ * 如果不存在,则生成一个新的256位密钥并存储在选项中
+ */
+// 检查密钥是否存在,如果不存在则生成并存储
+if (!get_option('sakura_encryption_key')) {
+ // 生成一个安全的 128-bit (16字节) 密钥,适用于 AES-128-CBC
+ $new_key = bin2hex(random_bytes(16)); // 或者使用 openssl_random_pseudo_bytes(16)
+ update_option('sakura_encryption_key', $new_key, false); // 'false' 表示不自动加载
+}
+
+// 在 init 钩子中设置全局变量
+add_action('init', function() {
+ global $sakura_privkey;
+ $sakura_privkey = get_option('sakura_encryption_key');
+});
diff --git a/inc/classes/QQ.php b/inc/classes/QQ.php
index 6f235f39..aaa11f1a 100644
--- a/inc/classes/QQ.php
+++ b/inc/classes/QQ.php
@@ -5,7 +5,21 @@
class QQ
{
public static function get_qq_info($qq) {
- $get_info = file_get_contents('https://api.qjqq.cn/api/qqinfo?qq=' . $qq);
+ // Validate QQ number: must be 3 or more digits
+ if (!preg_match('/^\d{3,}$/', $qq)) {
+ return array(
+ 'status' => 400,
+ 'success' => false,
+ 'message' => 'Invalid QQ number.'
+ );
+ }
+ $api_key = iro_opt('qq_avatar_api_key');
+ $query = http_build_query([
+ 'key' => $api_key,
+ 'qq' => $qq
+ ]);
+ $url = 'https://api.nsmao.net/api/qq/v1/query?' . $query;
+ $get_info = file_get_contents($url);
$name = json_decode($get_info, true);
if ($name) {
if ($name['code'] == 200){
@@ -13,8 +27,8 @@ public static function get_qq_info($qq) {
'status' => 200,
'success' => true,
'message' => 'success',
- 'avatar' => 'https://q2.qlogo.cn/headimg_dl?dst_uin=' . $qq . '&spec=100',
- 'name' => $name['name'],
+ 'avatar' => $name['data']['avatar'],
+ 'name' => $name['data']['name'],
);
}
} else {
@@ -30,9 +44,11 @@ public static function get_qq_info($qq) {
public static function get_qq_avatar($encrypted) {
global $sakura_privkey;
if (isset($encrypted)) {
- $iv = str_repeat($sakura_privkey, 2);
- $encrypted = base64_decode(urldecode($encrypted));
- $qq_number = openssl_decrypt($encrypted, 'aes-128-cbc', $sakura_privkey, 0, $iv);
+ $decoded = base64_decode(urldecode($encrypted));
+ $iv = substr($decoded, 0, 16); // 提取前16字节作为IV
+ $data = substr($decoded, 16); // 剩余是加密数据
+ $qq_number = openssl_decrypt($data, 'aes-128-cbc', $sakura_privkey, 0, $iv);
+
preg_match('/^\d{3,}$/', $qq_number, $matches);
return 'https://q2.qlogo.cn/headimg_dl?dst_uin=' . $matches[0] . '&spec=100';
}
diff --git a/opt/options/theme-options.php b/opt/options/theme-options.php
index 007062fd..c8203e3a 100644
--- a/opt/options/theme-options.php
+++ b/opt/options/theme-options.php
@@ -3158,6 +3158,14 @@ function iro_validate_optional_url( $value ) {
'default' => true
),
+ array(
+ 'id' => 'qq_avatar_api_key',
+ 'type' => 'text',
+ 'title' => __('QQ Avatar API Key','sakurairo_csf'),
+ 'desc' => __('Enter your API key for QQ avatar service, get your API key at: https://api.nsmao.net','sakurairo_csf'),
+ 'default' => ''
+ ),
+
array(
'id' => 'qq_avatar_link',
'type' => 'select',