PHP-метод для выполнения AES-шифрования по блокам для экономии памяти

Позвольте мне объяснить мою дилемму. В моем PHP-скрипте мне нужно иметь возможность шифровать файлы, загруженные на мой сайт. Я решил использовать AES-256 шифрование с помощью CBC (Цепь блоков шифра) режим работы.

Первоначально я обнаружил очень многообещающую функцию, которая могла бы делать это, которая работала бы так:

//Just the encryption part
$fileData = file_get_contents($serverFilePath);
$encData = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $binKey,
$fileData,
MCRYPT_MODE_CBC,
$binIV);

Описанный выше метод работает хорошо, за исключением одной серьезной проблемы: я размещаю свой сайт на учетной записи общего хостинга, и, как вы видите, mcrypt_encrypt Метод требует, чтобы данные были введены в него все сразу как двоичная строка. Это становится проблемой, если файл, который я шифрую, достаточно большой. В каком случае mcrypt_encrypt не удается, мой сценарий завершен, и пользователь видит пустую белую страницу … упс!

После этого я получаю следующее сообщение в error_log:

Неустранимая ошибка PHP: допустимый объем памяти X байтов исчерпан (попытался
выделить Y байт) в бла-бла

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

(Между прочим, вышеописанный метод дает сбой, когда я пытаюсь зашифровать файл размером всего 200 МБ, что не так уж много по сегодняшним стандартам.)

Таким образом, мой вопрос / дилемма:

Есть ли способ выполнить шифрование AES только на одном блоке открытого текста (без CBC или любого другого режима работы, просто старый AES), и если да, то я могу сделать CBC сам? Если да, я могу написать свой собственный метод, шифруя блок за блоком и, таким образом, избежать ошибок mcrypt_encrypt функция и не загружать весь файл в оперативную память.

Мы ценим любые предложения?

2

Решение

Вы можете смоделировать одиночное блочное шифрование AES, просто используя режим ECB для mcrypt_encrypt вместо режима CBC, а затем делать CBC самостоятельно. Режим ECB по существу не имеет состояния. Нет распространения от последнего зашифрованного блока, как в режиме CBC. Это просто применение AES к каждому блоку отдельно.

В зависимости от того, как вы выполняете потоковое чтение, может быть проще или более эффективно использовать фрагменты шифрования CBC. Вы все еще можете использовать свой метод для фрагментов файла для шифрования. Затем вы будете использовать последний блок зашифрованного текста в качестве IV для следующего фрагмента.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]