Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -2305,19 +2305,17 @@ function change_avatar($avatar)
preg_match('/:\"([^\"]*)\"/i', $qqavatar, $matches);
return '<img src="' . $matches[1] . '" class="lazyload avatar avatar-24 photo" alt="😀" width="24" height="24" onerror="imgError(this,1)">';
}

// 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);
Copy link
Preview

Copilot AI Aug 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a deterministic IV derived from the key weakens encryption security. The IV should be randomly generated for each encryption operation to ensure semantic security.

Copilot uses AI. Check for mistakes.


// 加密数据
$encrypted = openssl_encrypt($qq_number, 'aes-128-cbc', $sakura_privkey, 0, $iv);

// 将初始化向量和加密数据一起编码
$encrypted = urlencode(base64_encode($iv . $encrypted));

return '<img src="' . rest_url("sakura/v1/qqinfo/avatar") . '?qq=' . $encrypted . '" class="lazyload avatar avatar-24 photo" alt="😀" width="24" height="24" onerror="imgError(this,1)">';
} else {
// Handle the case where $sakura_privkey is not set or is null
Expand All @@ -2326,7 +2324,6 @@ function change_avatar($avatar)
}
return $avatar;
}

//生成随机链接,防止浏览器缓存策略
function get_random_url(string $url): string
{
Expand Down Expand Up @@ -4212,3 +4209,20 @@ function iro_action_operator()
}
}
iro_action_operator();


/* * 检查并生成加密密钥
* 如果不存在,则生成一个新的256位密钥并存储在选项中
*/
// 检查密钥是否存在,如果不存在则生成并存储
if (!get_option('sakura_encryption_key')) {
// 生成一个安全的 256-bit (32字节) 密钥
$new_key = bin2hex(random_bytes(32)); // 或者使用 openssl_random_pseudo_bytes(32)
update_option('sakura_encryption_key', $new_key, false); // 'false' 表示不自动加载
}

// 在 init 钩子中设置全局变量
add_action('init', function() {
global $sakura_privkey;
$sakura_privkey = get_option('sakura_encryption_key');
});
14 changes: 8 additions & 6 deletions inc/classes/QQ.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
class QQ
{
public static function get_qq_info($qq) {
$get_info = file_get_contents('https://api.qjqq.cn/api/qqinfo?qq=' . $qq);
$get_info = file_get_contents('https://api.nsmao.net/api/qq/v1/query?key=' . iro_opt('qq_avatar_api_key') . '&qq=' . $qq);
$name = json_decode($get_info, true);
if ($name) {
if ($name['code'] == 200){
$output = array(
'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 {
Expand All @@ -30,9 +30,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';
}
Expand Down
8 changes: 8 additions & 0 deletions opt/options/theme-options.php
Original file line number Diff line number Diff line change
Expand Up @@ -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','sakurairo_csf'),
'default' => ''
),

array(
'id' => 'qq_avatar_link',
'type' => 'select',
Expand Down