AES 128-битное дешифрование частичного файла CTR с помощью PHP

Это не дубликат, потому что я везде искал, и я не могу найти ответ на этот вопрос. О частичном расшифровке. Не полный.

Я хорошо знаю PHP, но мало знаю о криптографии. Я знаю ключ и iv из зашифрованного файла. Файл расшифровывается как прекрасный, но реальная проблема возникает, когда я пытаюсь расшифровать частичный файл из середины.

Он расшифровывается отлично, когда я пытаюсь дешифровать первые 128 кбайт файла или 256 кб или любую длину с самого начала файла. но когда я начинаю с середины, он не расшифровывается, а дает результат тарабарщины.

Я напишу здесь пример первых 100 байт файла.

Шифрование – это режим ATR 128 бит CTR.

Я использовал как mdecrypt_generic, так и mcrypt_decrypt функции PHP без успеха.

Используемый код:

$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 КБ) / 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; } не 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 собственный интерфейс загрузки использует несколько подключений и загружает файл в виде кусков, и есть еще один веб-сервис, который позволяет загружать из Mega с несколькими соединениями и возобновлять поддержку.

Мне нужно расшифровать частичный файл для поддержки запросов заголовков HTTP Range от менеджеров браузера / загрузки. Если запрос диапазона падает во втором или третьем блоке, мне нужно иметь возможность расшифровать этот блок и отправить его клиенту без дешифрования файла с самого начала.

Возможно ли это? Это должно быть потому, что какой-то веб-сайт уже сделал это.