В данной статье мы рассмотрим, как исправить ошибки в коде, предназначенном для расшифровки файлов ZIP, зашифрованных с использованием AES-256, в среде Delphi с помощью Crypto API. Эта проблема связана с использованием стандартного класса TZipFile для открытия архивов ZIP, а также с регистрацией обработчика сжатия следующим образом:
Функция DecompressStream использует метод AESDecryptStream для расшифровки потока, если файл зашифрован и метод сжатия соответствует AES-256:
function DecompressStream(InStream: TStream; const ZipFile: TZipFile; const Item: TZipHeader): TStream;
...
if isEncrypted and (ZipFile is TEncryptedZipFile) and (Item.CompressionMethod = zcAESEncrypted) then
LStream := AESDecryptStream(InStream, TEncryptedZipFile(ZipFile).Password, Item.CompressedSize)
...
Код для расшифровки AES представлен в функции AESDecryptStream. Он основан на примере, который, несмотря на свою сомнительность, является единственным доступным и утверждает, что работает для AES-128. Однако, при вызове функции CryptDecrypt() возникает ошибка "Bad Data".
Основные проблемы и их решения
Отсутствие salt-значения: Первые 16 байт файла должны использоваться как salt для AES-256. Необходимо добавить эту информацию в код, который отвечает за создание ключа.
Количество итераций: Для генерации ключа необходимо выполнить 1000 итераций.
Ошибки в коде: В вызове CryptHashData() необходимо убрать @ и использовать приведение типа PWideChar. Вместо WideString следует использовать UnicodeString, так как string в Delphi это UnicodeString.
Проблема с размером буфера: При последнем вызове CryptDecrypt() буфер может быть не полностью заполнен, что может вызывать ошибку "Bad Data". Необходимо убедиться, что буфер заполняется полностью перед расшифровкой.
Письмо данных в поток: Функция TStream.Write() не имеет перегруженной версии, которая принимает указатель. Необходимо либо дереференцировать указатель, либо использовать WriteData(), который принимает указатель.
Шаги исправления
Исправление типов данных: Используйте UnicodeString вместо WideString и приведите строку к PWideChar при вызове CryptHashData().
Добавление salt: Включите первые 16 байт файла в процесс создания ключа.
Итерации создания ключа: Убедитесь, что процесс создания ключа включает 1000 итераций.
Размер буфера: Проверьте, что размер данных для расшифровки соответствует размеру буфера, и добавьте необходимый объем нулей, если данные короче буфера.
Письмо данных: Используйте WriteData() для записи данных из буфера в поток.
Пример исправленного кода
function AESDecryptStream(InStream: TStream; const Password: string; FileSize: Integer): TStream;
...
keySize := Length(Password) * SizeOf(WideChar); // размер в байтах
...
// Включите salt в процесс создания ключа
...
// Убедитесь, что буфер заполнен полностью, если это необходимо
...
// Используйте WriteData для записи данных из буфера
fsOut.WriteData(lpBuffer, outLen);
Result.WriteData(lpBuffer, outLen);
...
Заключение
Приведенные шаги должны помочь в исправлении кода расшифровки AES-256 в Delphi. Важно внимательно изучить каждый шаг процесса и убедиться, что все требования, изложенные в документации Winzip по шифрованию AES, выполняются корректно.
Исправление ошибок в кодировании AES-256 для расшифровки файлов ZIP в Delphi с использованием Crypto API и класса `TZipFile`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.