前言
NexusPHP
多年前已停止更新,作为NexusPHP
的玩家都知道有个参数叫passkey
简称pk;passkey
可以做很多事情:RSS订阅站内种子
、下载站点所有种子
、上传下载时Tracker汇报
等;NexusPHP
搭建的很多站,下载链接内和种子announce字段都存在明文的passkey,没有进行任何加密。
很多用户在截图下载器Tracker错误或者在站点之间转种、发种时并未对明文的passkey做任何的处理,可见泄露passkey的几率很大。
passkey权限非常大,一旦泄露,严重者直接ban号,后患无穷!
鉴于以上情况,笔者觉得有必要对passkey的使用进行隔离、并限定权限,引入可操作性更强,更安全的加密算法来解决隐患!
解决方案
保留passkey
参数,新增hash
、authkey
参数,3个参数各用户独立
,并且hash参数按天变化
。
采用安全性很高的AES加密算法,无需读写数据库、无需读写缓存,节省资源。
$pass = '站点私钥'
$hash_crypt_key = sha1($SITENAME . $CURUSER["passkey"] . $pass . date("Ymd")) . $CURUSER["id"];
$authkey_crypt_key = sha1($SITENAME . $CURUSER['secret'] . $pass . '当前种子用户的首次下载时间') . $CURUSER['id'];
物理隔离
passkey
仅在usercp.php
,getrss.php
存在,在torrentrss.php
使用;hash
仅在download.php
使用;authkey
仅在种子文件的announce字段
存在,在announce.php
使用!
限定权限
限定passkey权限
:专用于生成RSS订阅链接,不能下载种子、不能Tracker汇报(移除种子内明文存在的passkey);限定hash权限
:专用于下载种子链接,不能RSS订阅、不能Tracker汇报;限定authkey权限
:专用于种子announce字段Tracker汇报,不能RSS订阅、不能下载种子;
达成效果
- 用户重置
passkey
仅影响RSS订阅页面链接,不影响Tracker汇报; - 种子下载使用的
hash
,每个用户、每个种子都不同,且按天变化; - 用户重置所有
authkey
,(更新$CURUSER['secret'])可以让所有种子Tracker失效; - 用户也可以重置单个种子的
authkey
,(更新‘当前种子用户的首次下载时间’)只影响当前种子的Tracker汇报; - 因种子announce字段的Tracker连接参数
authkey
是加密的,有效避免第三方分发种子源文件,所有种子必须从站点下载。
泄漏处理
- 种子
authkey泄漏
:只影响当前种子,用户只需重置当前单个种子的tracker即可,不影响其他; - 下载链接
hash泄漏
:因hash有效性只有一天,所以只影响当前单个种子,不影响其他,只需要重置当前单个种子的tracker即可; - 而
passkey
仅存在于RSS订阅链接,安全性仅次于用户的账号、密码,泄漏的可能性大大降低;
如果不幸passkey泄漏
:也无法下载站点所有种子,仅影响当前RSS订阅链接最多50个种子和泄漏之后更新的种子,用户可以先重置passkey
,然后查看种子下载记录,只需要重置已泄漏种子即可。
代码实现
index.php
<?php
/**
* RSS订阅权限:passkey
* 种子下载权限:hash(AES对称加密)
* Tracker权限:authkey(AES对称加密 | HASH加密)
*/
include __DIR__ .'/ICrypt.php';
$pass = '站点唯一的密钥';
$uid = '321611'; // 用户id
/**
* 种子下载链接加密
* @desc AES对称加密生成hash(受控于passkey,各用户拥有独立的passkey)
* 注意:重置passkey时,影响用户RSS订阅链接,不影响用户Tracker汇报;
*/
echo '------------------------------------'.PHP_EOL;
# 1. 根据用户uid查询出passkey
$passkey = 'MIIEowIBAAKCAQEA4T9gNTdx3jQXTWtsbz7V8BbNGxvLNNxdcOZiWmMreH8wFaeL';
# 2. 用户download加密key(每天变化)
$key = sha1($passkey . $pass . date("Ymd")) . $uid;
echo '用户download加密密钥:'.$key.PHP_EOL;
# 3. 加密参数
$config = [
'method' => 'AES-128-CBC', //加密方式 AES-256-CBC等
'key' => $key, //加密key
'iv' => md5($key, true), //保证偏移量为16位
];
# 4. 模拟加密解密的全部过程
$id = 9129016; // 种子id
while ($id > 9129013) {
$data = $uid.'.'.$id; // 原始数据
echo '原始数据:'.$data;
$hash = ICrypt::encode($data, $config); // 加密
echo ' | AES加密torrent_id:download.php?hash='.$hash.'&uid='.$uid.' ('.strlen($hash).'位)';
echo ' | AES解密torrent_id:'.ICrypt::decode($hash, $config).PHP_EOL; //解密
$id--;
}
/**
* 种子Tracker链接加密
* @desc AES对称加密生成hash(受控于secret,各用户拥有独立的secret)
* 优势:重置单个种子时,把torrent_id、uid、新secret写入数据表torrent_secret,不影响用户Tracker汇报、不影响用户RSS订阅连接;
* 注意:重置secret时,影响用户所有种子Tracker汇报,不影响用户RSS订阅连接(应删除数据表torrent_secret内当前用户数据)
*/
echo '------------------------------------'.PHP_EOL;
# 1. 根据用户uid查询出secret
$secret = 'biwbSB6Pqd/H1fmQSI28uLUzgwXCv1uAE3L2liy8WJOrcH9mxl9qMyBoeyB7QswG'; // 全局 用户独立
# 2. 用户tracker加密key
$key = sha1($secret . $pass) . $uid;
echo '用户Tracker加密密钥:'.$key.PHP_EOL;
# 3. 加密参数
$config = [
'method' => 'AES-128-CBC', //加密方式 AES-256-CBC等
'key' => $key, //加密key
'iv' => md5($key, true), //保证偏移量为16位
];
# 4. 模拟加密解密的全部过程
$id = 412900016; // 种子id
while ($id > 412900013) {
$data = json_encode(['id' => $id,'uid' => $uid], JSON_UNESCAPED_UNICODE); // 原始数据
echo '原始数据:'.$data;
$hash = ICrypt::encode($data, $config); // 加密
echo ' | 方法一.AES加密Tracker:announce.php?authkey='.$hash.'&uid='.$uid.' ('.strlen($hash).'位)';
echo ' | AES解密Tracker:'.ICrypt::decode($hash, $config); // 解密
echo ' | 方法二.hash_hmac签名Tracker:announce.php?authkey='.$uid.'.'.sha1($key.$id).PHP_EOL;
$id--;
}
echo '------------------------------------'.PHP_EOL;
备注:为进一步提高安全性,在生成$key变量时,可以加入站点唯一的密钥作为参数:$key = sha1($passkey . $pass . date("Ymd")) . $uid;
和 $key = sha1($secret . $pass) . $uid;
。
ICrypt.php
<?php
/**
* @copyright (c) 2020 www.iyuu.cn
* @file ICrypt.php
* @brief 加密解密
* @author david
* @date 2020年7月16日
*/
class ICrypt
{
/**
* @brief MD5加密方法
* @param string $string 字符串
* @return string $string 加密后的字符串
*/
public static function md5($string)
{
return md5($string);
}
/**
* @brief SHA1加密方法
* @param string $string 字符串
* @return string $string 加密后的字符串
*/
public static function sha1($string)
{
return sha1($string);
}
/**
* @brief base64url加密方法
* @param String $str 字符串
* @return String $str 加密后字符串
*/
public static function base64url_encode($str)
{
return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
}
/**
* @brief base64url解密方法
* @param String $str 字符串
* @return String $str 解密后的字符串
*/
public static function base64url_decode($str)
{
return base64_decode(str_pad(strtr($str, '-_', '+/'), strlen($str) % 4, '=', STR_PAD_RIGHT));
}
/**
* @brief 动态加密函数
* @param String $string 字符串
* @param Array $config 加密参数
* @return String 加密后的字符串
*/
public static function encode($string, $config = array())
{
return self::base64url_encode(openssl_encrypt($string, $config['method'], $config['key'], OPENSSL_RAW_DATA, $config['iv']));
}
/**
* @brief 动态解密函数
* @param String $string 字符串
* @param Array $config 解密参数
* @return String 解密后的字符串
*/
public static function decode($string, $config = array())
{
$string = openssl_decrypt(self::base64url_decode($string), $config['method'], $config['key'], OPENSSL_RAW_DATA, $config['iv']);
return rtrim(rtrim($string, chr(0)), chr(7));
}
}
附件:点此下载crypt.zip
测试结果
------------------------------------
用户download加密密钥:df6ac9b443bc950135197fa7b641f5824b4908de321611
原始数据:321611.9129016 | AES加密torrent_id:download.php?hash=TFTresyZBATrwz5krs43-g (22位) | AES解密torrent_id:321611.9129016
原始数据:321611.9129015 | AES加密torrent_id:download.php?hash=i1oWHot5YmGUatgN92AmMw (22位) | AES解密torrent_id:321611.9129015
原始数据:321611.9129014 | AES加密torrent_id:download.php?hash=DEOZ0sF-Wiqmjn_RRGlQfw (22位) | AES解密torrent_id:321611.9129014
------------------------------------
用户Tracker加密密钥:68a73366b45f4cb06e66f6ad279e928aa2f6828b321611
原始数据:{"id":412900016,"uid":"321611"} | 方法一.AES加密Tracker:announce.php?authkey=93KtavYRAbpbkty0u9jNOinIqg4jbrgE5LKJjx8CRvs (43位) | AES解密Tracker:{"id":412900016,"uid":"321611"} | 方法二.HASH加密Tracker:announce.php?authkey=321611.9b6f84f85bb67b259ec1cb7804951bf1a65b2f58
原始数据:{"id":412900015,"uid":"321611"} | 方法一.AES加密Tracker:announce.php?authkey=c56fORCZym3TxALzWGwO5Zw4a3Tt_OSl9acaXgjtKWw (43位) | AES解密Tracker:{"id":412900015,"uid":"321611"} | 方法二.HASH加密Tracker:announce.php?authkey=321611.0de0d726a765cc019d24cf8ac960986ec3e1d4cc
原始数据:{"id":412900014,"uid":"321611"} | 方法一.AES加密Tracker:announce.php?authkey=qNFx6MuF9TVd9N0HbGbkbbg8v3S8lZzJil64R6xAXAM (43位) | AES解密Tracker:{"id":412900014,"uid":"321611"} | 方法二.HASH加密Tracker:announce.php?authkey=321611.d01a2ce758257456f7c24016a72e55baa53de441
------------------------------------
版权属于:大卫科技Blog
本文链接:https://www.iyuu.cn/archives/397/
转载时须注明出处