这不是重复的帖子,因为我到处都看过,但找不到答案。它关于部分解密。不满。
我对 PHP 有很好的了解,但对密码学知之甚少。我知道加密文件的密钥和 iv。该文件整体解密良好,但当我尝试从中间解密部分文件时出现真正的问题。
当我尝试解密文件的前 128kb 或 256kb 或文件开头的任何长度时,它解密得很好。但是当我从中间开始时,它不会解密而是给出乱码输出。
我将在这里发布文件前 100 个字节的示例。
加密为 AES 128 位 CTR 模式。
我使用了 PHP 的 mdecrypt_generic 和 mcrypt_decrypt 函数都没有成功。
使用的代码:
$chunk2 = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, base64_decode($mega_key), $data, 'ctr', base64_decode($mega_iv));
echo base64_encode($data) .'<br />'. base64_encode($chunk2);
结果:
9PX2fU83NF3hLc+HFdyHkqfxC4bHWKUQwQHJkNVnYbKCIQrhlHvTKtz8T3Bb0TgBkyBoGHnDCzZs3bu54KLQ8Bv0lzrTVJbzJY5msBfcy7Zi2Z/fLoMm+nvqdGPTNR0uwv45xJ8=
MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTE=
如你看到的。解密后,结果是文件的前 100 个字节包含数字 1的序列。该文件由 Mega.co.nz 使用 JavaScript 加密。根据 Mega 的文档,该文件已被分块加密以进行部分加密/解密。
文件加密
MEGA 使用客户端加密/解密来端到端保护文件传输和存储。从客户端接收的数据被逐字存储和传输;服务器既不解密也不重新加密,也不验证传入用户文件的加密。所有加密处理都在最终用户的控制之下。为了允许进行完整性检查的部分读取,文件被视为一系列块。为了简化服务器端处理,部分上传只能在块边界上开始和结束。此外,部分下载只有在满足相同标准时才能进行完整性检查。块边界位于以下位置:0 / 128K / 384K / 768K / 1280K / 1920K / 2688K / 3584K / 4608K /。(每 1024 KB)/EOF
我正在使用此函数计算文件的块边界:
public function get_chunks($size)
{
$chunks = array();
$p = $pp = 0;
for ($i = 1; $i <= 8 && $p < $size - $i * 0x20000; $i++) {
$chunks[$p] = $i * 0x20000;
$pp = $p;
$p += $chunks[$p];
}
while ($p < $size) {
$chunks[$p] = 0x100000;
$pp = $p;
$p += $chunks[$p];
}
$chunks[$pp] = ($size - $pp);
if (!$chunks[$pp])
{
unset($chunks[$pp]);
}
return $chunks;
}
我曾尝试单独解密第二个块,但失败了。由于显而易见的原因,我无法在此处发布 128kb 的块,但我将向您展示从第 2 个字节到第 100 个字节的块。这是相同代码的结果:
使用的代码:
$chunk2 = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, base64_decode($mega_key), $data, 'ctr', base64_decode($mega_iv));
echo base64_encode($data) .'<br />'. base64_encode($chunk2);
结果:
9fZ9Tzc0XeEtz4cV3IeSp/ELhsdYpRDBAcmQ1WdhsoIhCuGUe9Mq3PxPcFvROAGTIGgYecMLNmzdu7ngotDwG/SXOtNUlvMljmawF9zLtmLZn98ugyb6e+p0Y9M1HS7C/jnEnw==
MDK6A0kyWI3903mj+GokBGfLvHCuzITg8flodIM34gGSGtpE3pnIxxGCDhq72AijgnlBUIv5DGuAVzNoc0MR2t5SnNi281TnmtnnlvomTOWKd3HAnJTtsKCvJoHXGQLdDfbMag==
结果与mcrypt_module_open('rijndael-128', '', 'ctr', '');
我需要部分解密文件,因为我正在尝试为支持并行连接/恢复支持的 Mega 编写开源下载管理器。
我需要即时解密文件以允许文件流式传输,因此下载后解密是不可能的。
在 mega 的网站上,他们自己的下载界面使用多个连接并以块的形式下载文件,还有另一个 Web 服务允许从 Mega 下载具有多个连接和恢复支持。
我需要解密部分文件以支持来自浏览器/下载管理器的 HTTP Range 标头请求。如果范围请求落在第二个或第三个块中,我需要能够解密该块并将其发送给客户端,而无需从头开始解密文件。
甚至可能吗?应该是因为有些网站已经做到了。