Добрый день, есть у меня следующая задачка: Есть некое приложение (не мое), оно плотненько работает с файлами. Необходимо сделать перехват функций чтения/записи и добавить расшифрование/шифрование так, чтобы размер файлов не менялся (приложение читает по определенным оффсетам). Перехват сделать несложно (приложение юзермод, перехват локально в процессе без использования драйверов, это НЕ спайваре или троян). Какой шифр лучше взять (требования к шифрованию минимальные, главное, чтоб не XOR)? Как я понял RC4 не подойдет в связи с тем, что невозможно проверить валидность при расшифровке. RSA (пусть даже 32бита) тоже мимо, т.к. вроде размер шифртекста будет кратен ключу. Блочные тоже не подходят за исключением ГОСТ`а с режимом CFB, но он тоже вроде не проверяет при расшифровке. Пока что на ум приходит шифровать первые байты RSA. Но тут еще одна трабла: приложение использует маппинг, реально ли в этом случае перехвать чтение/запись?
Подойдет любой хороший поточный шифр, например финалисты проекта eStream http://www.ecrypt.eu.org/stream/ Валидность после расшифровки проверяй либо обычной crc32 либо чем покруче mdX/SHA1/2 etc. либо каким нибудь PKCS#5 паддингом Если надо убедиться что хэш не подделали, подписывай его RSA/DSA/DH/ECC/
При маппинге чтение/запись реализуется в диспетчерах кэша/памяти, поэтому именно чтение/запись в юзер-моде перехватить не удасться... в юзер-моде только перехват функций, реализующих маппинг - но это гемор...
Scratch но размер буфера не должен измениться, т.е. если файл был 100 байт, то таким и должен остаться, т.е. дописать хеш к куску шифртекста нельзя. А проверить валидность хешом тоже никак, каккие будут писаться данные - заранее неизвестно. т.к. gorodon спасибо, значит буду только readfile,writefile перехватывать.
+ если приложение будет читать файл кусками по рандомным офсетам, то как быть? Тогда нужен шифр, который не зависит от положения байт в открытом тексте? Это какой тогда?
Не знаю насчёт поточных шифров, но в случае блочного алгоритма при обработке операции записи в этом случае придётся сначала прочитать и расшифровать весь блок, на который указывает смещение, затем изменить этот блок в соответствии со вновь записываемыми данными, и только после этого зашифровать и записать блок обратно. Если в операции участвуют несколько блоков, то всё чуть сложнее, т.к. придётся ещё и с последним блоком выполнять аналогичную процедуру. С блочными шифрами тут только один косяк - шифротекст обычно длиннее, чем исходные данные, но разве это большая проблема? А про поточные шифры пусть более сведующие товарищи расскажут, как быть в этой ситуации.
Да, но только на уровне ядра. Писать файловый фильтр, перехватывать I/O подкачки плюс некэшируемый I/O, который пишется сразу на диск, минуя кэш. Ну всё как обычно, в общем.
в этом и проблема, допустим приложение записало 2 блока: 5 байт и 10 байт после шифровки получилось 2 блока по 16 байт (например). Когда приложение потом будет читать из офсета 4 (который указывал на 2-й блок в открытом тексте), то будет фейл, т.к. в этом месте идет зашифрованный блок 1. Проблема решиться, если использовать XOR: длина не увеличивается, шифр не зависит от положения открытого текста, но не проходит по сложности "шифра" + нельзя проверить корректность расшифровки )))
Насколько я понял, то мне нужен шифр с сцеплением блоков (ECB, CBC) для проверки валидности. Даже если и есть поточный шифр с ECB/CBC режимом, то все равно при чтении/записи по рандомному офсету получится каша (если конечно нет возможности инициализировать начальное значение гаммы в соответствии с позицией в файле). Получается, что подходит только 8-ми битный блочный шифр ))) Так? ))) Но он тогда не будет отличаться от ксора. Или делать свой менджер, который будет по 100500 раз файл считывать перешифровывать записывать при записи в него. Но это все слишком сложно (для такой простой задачи)
В общем, думаю, что проблему решит поточный шифр с режимом CBC, в котором можно настроить начальный вектор. Чтобы, например, при шифровании можно было бы взять текущую позицию в файле и с помощью нее настроить начальный вектор, при этом тогда не будет каши. Подскажите, знатоки?
Ну во-первых все таки наверное блочный, во-вторых CBC не обеспечивает аутентификации, если один из блоков повредить, то через один блок уже все нормально будет https://secure.wikimedia.org/wikipedia/ru/wiki/Режим_сцепления_блоков_шифротекста Если читаешь\пишешь из рендомных кусков, то для этого случая специально придумали режим XTS в котором шифруют TrueCrypt и DiskCryptor
Scratch возможно получиться в этом XTS (или XEX), только вот не могу найти либы, в которых есть реализация. А также примеры. Как я понял, то возможно зашифровать/расшифровать данные по любому офсету любого размера?
Scratch Я это знаю. В трукрипте они же и используются. Вроде AES-XTS уже почти стандарт. Глянул исходники трукрипта - с разбегу не разобрался. Может есть коротенькие примеры? Мне надо представить файл, в который пишет программа, в виде контейнера? И как с ним работать? Я уже запутался.
Если Вы не добавляете никакой дополнительной информации к обрабатываемым данным, то проверить их неповрежденность самим процессом обратной обработки (расшифрованием в Вашем случае) - нельзя. Чудес не бывает. Энтропию информации процессом шифрования изменить нельзя. Все алгоритмы обнаружения ошибок добавляют контрольные данные. Либо Вы реализуете проверку целостности анализируя семантику расшифрованных данных (например, исходными данными является исключительно текст на латинице+цифры и запятые), либо проверяете дополнением контрольными разрядами по той или иной схеме. Третьего не дано. Кстати, про 8-битное блочное шифрование. Это не совсем XOR. Это 8-битная биективная функция, закон отображения реализуемый в которой зависит от позиции в файле (я подразумеваю режим CTR или аналогичные). Да, конечно, есть угрозы, возникающие, если у злоумышленника будут доступны пары "открытый/закрытый текст" именно для этой позиции. Но они не настолько критичны, как при простом XOR-е.
Ясно. А как же RSA? А AES-XTS добавляет эту избыточную информацию? Трукрипт же проверяет целостность или он хранит хеши в другом месте? Мне достаточно выявление ошибки в 1 бите.
подскажите плиз, а для моей задачи подойдет EFS? что-то не нашел функций, которыми можно расшифровывать файлы НЕ ключами текующего пользователя системы, а своими, вшитыми в программу.
такое ощущуение, что тут монолог... ((( Scratch спасибо за наводку на XTS. Вроде немного разобрался с AES-XTS. Как я понял, то вся его фишка в том, то данные шифруются секторами. А не проще ли сделать тоже самое самому? Т.е. при перехвате Read/Write смотрим по какому офсету происходит обращение. Если запись, то: сохраняем указатель в файле определяем какие сектора в нашем контейнере подлежат записи читаем зашифрованные "сектора" из контейнера расшифровываем вносим изменения шифруем записываем обратно в контейнер восстанавливаем указатель в файле обновляем хеш измененных "секторов" При чтении аналогично. При этом можно использовать быстрые шифры, такие, как RC4. Реализуемо за день максимум. Конечно можно было бы не изобретать квадратный велосипед, но т.к. не подсказали, то пришлось. Описанный мной алгоритм коррелирует с ТруКрипт и режимом XTS?