Современная операционная система представляет собой сложный иерархический процесс обработки и управления информацией.
Текущие версии ОС Windows в этом вопросе не являются исключением.
Чтобы интегрировать инструмент безопасности в среду ОС Windows, зачастую достаточно встроить его на уровне приложения.
Однако когда дело доходит до шифрования информации в среде ОС Windows, все становится гораздо сложнее.
Основной «головной болью» разработчика средства шифрования в этом процессе является обеспечение «прозрачности шифрования», т.е.
необходимо гармонично интегрироваться в структуру процессов операционной системы и в то же время гарантировать, что пользователи не будут вовлечены в процесс шифрования.
, тем более его обслуживание.
Требования к современным средствам безопасности все больше исключают пользователя из процесса защиты информации.
Таким образом, самому этому пользователю создаются комфортные условия, не требующие принятия «непонятных» решений по защите информации.
В этой статье будут обсуждаться идеи эффективной интеграции инструментов шифрования диска с процессами файловой системы Windows. Целью разработчиков было создать механизм шифрования информации на диске, отвечающий требованиям максимальной прозрачности для пользователей.
Требования необходимо будет выполнить за счет эффективного взаимодействия этого механизма шифрования с процессами операционной системы Windows, отвечающими за управление файловой системой.
Эффективность механизма шифрования также должна быть подтверждена высокой производительностью процессов шифрования и рациональным использованием ресурсов операционной системы.
Изначально задачей было обеспечить одновременный доступ к зашифрованному и расшифрованному контенту, а также зашифровать имена файлов.
Это порождает основные трудности, потому что.
Это требование противоречит существующей архитектуре Windows. Чтобы понять суть проблемы, сначала следует рассмотреть некоторые основные моменты данной операционной системы.
В Windows все файловые системы полагаются на такие подсистемы, как диспетчер памяти и диспетчер кэша, а диспетчер памяти, в свою очередь, опирается на файловые системы.
Казалось бы, замкнутый круг, но все станет ясно позже.
Ниже, на рисунке 1, показаны перечисленные компоненты, а также менеджер ввода-вывода, принимающий запросы от подсистем (например Win32) и от других системных драйверов.
На рисунке также используются термины «фильтр» и «стек файловой системы», которые будут рассмотрены более подробно ниже.
Изображение 1
Давайте рассмотрим такой механизм, как отображение файла в памяти.
Суть его заключается в том, что при обращении к виртуальной памяти фактически считывается часть файла.
Это реализуется с помощью аппаратных механизмов процессоров и самого менеджера памяти.
Любые диапазоны виртуальной памяти процесса описываются дескрипторами.
Если для определенного диапазона нет дескриптора, то в этой области виртуальной памяти ничего нет, и доступ к такому диапазону неизбежно приводит к сбою процесса.
Если физическая память назначена диапазону, доступ к этим виртуальным адресам приводит к обычному доступу к физической памяти, которая также называется анонимной памятью.
Если файл отображается в виртуальную память, то при обращении к этим адресам часть файла считывается с диска в физическую память, после чего доступ к нему будет осуществляться обычным способом.
Те.
Эти два случая очень похожи, с той лишь разницей, что в последнем сначала часть файла будет прочитана в соответствующую физическую память.
Дескриптор содержит информацию обо всех таких типах доступа.
Эти дескрипторы представляют собой структуры диспетчера памяти, которыми он управляет для выполнения необходимых задач.
Как нетрудно догадаться, чтобы прочитать часть файла в страницу физической памяти, диспетчер памяти должен отправить запрос файловой системе.
На рис.
2 показан пример виртуальной памяти процесса с двумя диапазонами A и B, к которым никогда не обращались.
фигура 2
Диапазон A отображается в исполняемый файл самого процесса, а диапазон B — в физическую память.
Теперь, когда процесс впервые обращается к диапазону A, диспетчер памяти возьмет на себя управление и первое, что он сделает, — это оценит тип диапазона.
Поскольку файл отображается в диапазон А, менеджер памяти сначала считывает соответствующую его часть из файла в физическую память, а затем отображает ее в диапазон А процесса, таким образом, дальнейший доступ к прочитанному содержимому будет осуществляться без использования памяти.
менеджер.
Для диапазона B диспетчер памяти выполнит ту же последовательность действий, с той лишь разницей, что вместо чтения данных из файла он просто сопоставит свободные страницы физической памяти с диапазоном B, после чего доступ к этому диапазону будет осуществляться без участия диспетчера памяти.
На рис.
3 показан пример виртуальной памяти процесса после первого доступа к диапазонам A и B. Рисунок 3
Как видно из рисунка, при обращении к обоим диапазонам доступ к физической памяти осуществляется без участия диспетчера памяти, т.к.
раньше при первом обращении он отображал физическую память на диапазоны А и В, а предварительно читал часть соответствующий файл в физическую память диапазона A. Менеджер кэша — это центральный механизм для всех открытых файлов в системе на всех дисках.
Использование этого механизма не только ускоряет доступ к файлам, но и экономит физическую память.
Менеджер кэша не работает сам по себе, в отличие от менеджера памяти.
Он полностью управляется файловыми системами и вся необходимая информация о файлах (например, размер) предоставляется ими.
Всякий раз, когда в файловую систему поступает запрос на чтение/запись, файловая система не читает файл с диска; вместо этого он вызывает службы диспетчера кэша.
Менеджер кэша, в свою очередь, используя услуги менеджера памяти, отображает файл в виртуальную память и копирует его из памяти в буфер запрашивающей стороны.
Соответственно, при обращении к этой памяти менеджер памяти отправит запрос к файловой системе.
И это будет специальный запрос, в котором будет сказано, что файл необходимо прочитать прямо с диска.
Если вы получаете доступ к файлу, который ранее был сопоставлен диспетчером кэша, он не будет переназначен на виртуальную память.
Вместо этого менеджер кэша будет использовать виртуальную память, в которую ранее был сопоставлен файл.
Сопоставление файлов отслеживается через структуры, которые файловые системы передают менеджеру кэша при вызове его служб.
Эти структуры будут рассмотрены более подробно ниже.
На рисунке 4 показан пример процесса чтения файла.
Рисунок 4
Как показано на рисунке выше, процесс считывает файл в буфер B. Для выполнения чтения процесс обращается к диспетчеру ввода-вывода, который генерирует и отправляет запрос к файловой системе.
Файловая система при получении запроса не читает файл с диска, а вызывает менеджер кэша.
Затем диспетчер кэша оценивает, сопоставлен ли файл с его виртуальной памятью, и если нет, он вызывает диспетчер памяти для сопоставления файла/части файла.
В этом примере файл уже отображается, и к нему никогда не обращались.
Затем диспетчер кэша копирует файл, сопоставленный с диапазоном виртуальной памяти A, в буфер обработки B. Поскольку доступ к диапазону A осуществляется впервые, диспетчер памяти возьмет на себя управление, затем он оценит диапазон, и, поскольку это память -mapped файла, часть его считать физической памятью, после чего он отобразит ее в диапазон виртуальной памяти A. После этого, как описано ранее, будет осуществлен доступ к диапазону A в обход диспетчера памяти.
Ничто не мешает вам одновременно кэшировать файл и отображать его в памяти столько раз, сколько захотите.
Даже если файл кэшируется и отображается в памяти десятками процессов, физическая память, используемая для этого файла, будет той же самой.
В этом суть экономии физической памяти.
На рис.
5 показан пример, в котором один процесс обычно читает файл, а другой процесс отображает тот же файл в свою виртуальную память.
Рисунок 5
Как видно на рисунке выше, физическая память отображается в виртуальную память процесса B и виртуальную память менеджера кэша.
Когда процесс A считывает файл в буфер D, он обращается к диспетчеру ввода-вывода, который сгенерирует и отправит запрос к файловой системе.
Файловая система, в свою очередь, свяжется с кэш-менеджером, который просто скопирует файл, отображенный в область виртуальной памяти C кэш-менеджера, в буфер D процесса A. Поскольку на момент обращения к кэш-менеджеру файл не был только уже сопоставленного, но и ранее выполненного доступа к диапазону C, в который отображается файл, операция будет выполнена без участия диспетчера памяти.
Процесс B при чтении/записи диапазона E по существу будет иметь доступ к тем же физическим страницам памяти, к которым имел доступ менеджер кэша при копировании файла.
Файловые системы принимают запросы от пользовательского программного обеспечения или других драйверов.
Перед доступом файл должен быть открыт. Если запросы на открытие/создание файла успешно завершены, файловая система сформирует структуры памяти, которые используются менеджером кэша и менеджером памяти.
Следует также отметить, что эти структуры уникальны для файла.
Те.
если конкретный файл диска был открыт в тот момент, когда поступил такой же запрос на этот же файл, файловая система будет использовать ранее сформированные структуры памяти.
По сути, они являются программным представлением дискового файла в памяти.
На рисунке 6 показан пример соответствия между экземплярами открытых файлов и их структурами.
Рисунок 6
На рисунке процесс A открыл файл C и файл D, а процесс B дважды открыл файл C. Таким образом, существует три открытых копии файла C, когда структура, образуемая файловой системой, всего одна.
Файл D был открыт один раз, поэтому открыт один экземпляр, соответствующий структуре, сформированной файловой системой.
Любые запросы к файловой системе не обрабатываются ею немедленно.
Запросы сначала проходят через цепочку драйверов, которые желают отслеживать такие запросы.
Такие драйверы называются фильтрами.
У них есть возможность просматривать запросы до того, как они достигнут файловой системы, а также после того, как файловая система их обработала.
Например, фильтр шифрования файлов может отслеживать запросы на чтение/запись для расшифровки/шифрования данных.
Таким образом, не модифицируя сами файловые системы, мы можем зашифровать данные файлов.
Фильтры могут привязывать свои уникальные данные к файловым структурам, создаваемым файловой системой.
Вместе драйверы фильтра и драйвер файловой системы образуют стек файловой системы.
Количество фильтров может быть разным, да и сами фильтры тоже могут быть разными.
Теоретически их может вообще не быть, но на практике этого не происходит. На рис.
7 показан стек файловой системы, содержащий три фильтра.
Рисунок 7
Прежде чем запрос достигнет файловой системы, он последовательно проходит через фильтры 1, 2 и 3. Когда запрос обрабатывается файловой системой, он рассматривается фильтрами в обратном порядке, т.е.
запрос проходит последовательно через фильтры 3, 2. и 1. Кроме того, в приведенном выше примере фильтр 1 и фильтр 3 привязали свои структуры к файловой структуре, которую файловая система сформировала после выполнения запроса на открытие/создание файла.
Подавляющее большинство задач решается с помощью фильтрации, но наш случай уникален.
Как отмечалось ранее, он уникален тем, что требует одновременного доступа к зашифрованному и расшифрованному контенту, а также к зашифрованным именам файлов.
Однако мы попробуем разработать фильтр, который решит эту проблему.
На рисунке 8 показана ситуация, когда файл ранее был открыт в расшифрованном виде.
Рисунок 8
Это означает, что фильтры увидели расшифрованное имя, и они, как показано на рисунке, могут привязать это имя к структуре, которую сформирует файловая система (как было сказано ранее, эта структура уникальна для конкретного файла диска) для дальнейшего манипуляции с файлом.
И в этот момент файл открывается зашифрованный, а это значит, что фильтры увидели зашифрованное имя.
Как они поведут себя в ситуации, когда к файловой структуре уже привязано расшифрованное имя? Очевидно, что поведение непредсказуемо, хотя последствия не обязательно фатальны.
В продолжение описанного выше можно добавить, что при доступе к содержимому файла также возникают проблемы, причем гораздо более серьезные.
Вернемся к ситуации, когда файл открывался и в расшифрованном, и в зашифрованном виде.
Эта ситуация показана на рисунке 9; файл никогда не был прочитан/записан.
Рисунок 9
Теперь представьте, что пришел запрос на чтение расшифрованного контента.
Файловая система будет использовать услуги менеджера кэша и передавать ему файловую структуру, к которой и менеджер кэша, и менеджер памяти будут привязывать свои уникальные данные для дальнейшего управления отображением и кэшированием файла.
Эта ситуация изображена на рисунке 10. Рисунок 10
Далее идет запрос на чтение зашифрованного содержимого, и файловая система снова передает файловую структуру менеджеру кэша, а поскольку менеджер кэша и менеджер памяти ранее привязали уникальные данные для этого файла к этой структуре, они просто будут использовать ее для выполнения запрос.
Те.
Теперь эти структуры будут указывать, куда был сопоставлен файл, а менеджер кэша просто скопирует данные файла из виртуальной памяти в буфер запрашивающей стороны.
Мы помним, что файл был кэширован в расшифрованном виде при первом обращении к нему, поэтому при зашифрованном доступе буфер запрашивающей стороны будет содержать расшифрованные данные.
Мы только что рассмотрели две фундаментальные проблемы.
На практике их было больше.
Например, в рамках задачи необходимо добавить информацию заголовка к каждому зашифрованному файлу, что также невозможно решить с помощью фильтрации.
Чтобы обойти все эти проблемы сразу, было найдено решение – виртуальная файловая система.
Виртуальная файловая система по своей сути мало чем отличается от обычной.
Коренное отличие состоит в том, что обычная файловая система работает с диском, а виртуальная — с файлами других файловых систем, т.е.
является общим потребителем сервисов файловой системы.
Рисунок 11 иллюстрирует концепцию виртуальной файловой системы.
Рисунок 11
В отличие от обычных файловых систем, виртуальная файловая система не регистрируется в системе (выше об этом не говорилось, но для того, чтобы операционная система могла пользоваться услугами конкретной файловой системы, она должна зарегистрироваться), а если да, то запрашивает отправлены туда не будут. Для решения этой проблемы мы используем фильтр обычной файловой системы, но на этот раз его функции будут очень простыми и ограниченными, одна из них (и основная) — отслеживание доступа к зашифрованным файлам.
Как только фильтр увидит такой запрос, он просто перенаправит его в виртуальную файловую систему.
При обращении к обычному файлу запрос будет передан в исходную файловую систему.
Теперь давайте еще раз посмотрим на расшифрованный и зашифрованный доступ, но в контексте виртуальной файловой системы.
На рис.
12 показан пример доступа к расшифрованному и зашифрованному содержимому определенного файла.
Рисунок 12
Еще раз представьте себе ситуацию, когда файл был открыт в расшифрованном виде.
Это значит, что при выполнении запроса на открытие файла наш фильтр увидел его и перенаправил в виртуальную файловую систему.
Виртуальная файловая система при получении запроса оценивает тип доступа (расшифрованный или зашифрованный), и поскольку осуществляется расшифрованный доступ, виртуальная файловая система сначала преобразует расшифрованное имя в зашифрованное, а затем пытается открыть файл.
файл через собственную файловую систему под этим именем (т. е.
файл имени в собственной файловой системе будет зашифрован).
В случае успеха виртуальная файловая система сформирует структуры памяти, которые позже будут использовать менеджер кэша и менеджер памяти.
Теперь представьте, что файл открывается в зашифрованном виде, фильтр снова пересылает запрос в виртуальную файловую систему, не производя никакой оценки.
Виртуальная файловая система оценивает тип доступа, и, поскольку доступ зашифрован, она просто попытается открыть файл с этим именем через собственную файловую систему.
Опять же, в случае успеха виртуальная файловая система сгенерирует структуры памяти для менеджера кэша и менеджера памяти.
Но в отличие от расшифрованного доступа, это будут разные структуры.
Теперь, если файл открывается повторно в расшифрованном виде, виртуальная файловая система использует те же структуры, которые она сформировала при первом расшифрованном доступе.
Если файл открывается повторно в зашифрованном виде, файловая система использует структуры, которые она сформировала при первом зашифрованном доступе.
Таким образом, мы разделили доступ к расшифрованному и зашифрованному контенту.
На рисунке 13 показана ситуация, когда доступ на чтение/запись к расшифрованному и зашифрованному содержимому файла никогда не выполнялся.
Рисунок 13
Теперь, если будет произведено расшифрованное чтение, виртуальная файловая система, используя услуги менеджера кэша, как показано на рисунке 14, передаст ей те структуры памяти, которые она вернула при открытии расшифрованного файла.
Рисунок 14
Менеджер кэша сопоставит файл с виртуальной памятью и скопирует данные в буфер запрашивающей стороны.
Соответственно, в процессе копирования диспетчер памяти отправит запрос на чтение в виртуальную файловую систему, которая, в свою очередь, отправит запрос на чтение в собственную файловую систему, а поскольку структуры памяти для расшифрованного файла были переданы в диспетчер кэша , виртуальная файловая система расшифрует данные и сообщит о завершении диспетчеру памяти.
Именно так расшифрованный контент кэшируется.
Если выполняется зашифрованное чтение, виртуальная файловая система передаст, как показано на рисунке 15, кэш менеджеру структур памяти, которые она сформировала при открытии зашифрованного файла.
Рисунок 15
Менеджер кэша снова сопоставит файл с виртуальной памятью (поскольку файл еще не был отображен в этих структурах) и скопирует данные в буфер запрашивающей стороны.
И опять же, в процессе копирования менеджер памяти отправит запрос на чтение в виртуальную файловую систему, которая снова отправит запрос на чтение в собственную файловую систему, а поскольку диспетчеру кэша были переданы структуры памяти для зашифрованного файла, то , не расшифровывая данные, виртуальная файловая система сообщит диспетчеру памяти о завершении.
Таким образом, файл кэшируется в зашифрованном виде.
Как мы видим, виртуальная файловая система решает фундаментальные проблемы, не позволяющие одновременно получить доступ к расшифрованному и зашифрованному содержимому файла, из-за чего приходится отказаться от классических механизмов операционной системы.
В процессе фильтрации мы можем только добавлять данные в структуры файловой памяти, которые возвращает файловая система, и поскольку мы не формируем эти структуры, мы не можем вмешиваться в них или манипулировать ими.
А через виртуальную файловую систему мы их полностью формируем, а значит, имеем над ними полный контроль, что необходимо при решении этой задачи.
Например, нам необходимо обеспечить согласованность между расшифрованным и зашифрованным содержимым файлов.
Представьте себе ситуацию, когда данные были записаны в расшифрованный файл, но данные все еще находятся в кеше, а не на диске.
И в этот момент приходит запрос на чтение зашифрованного содержимого файла.
В ответ виртуальная файловая система сбрасывает расшифрованное содержимое на диск и очищает зашифрованный кэш, в результате чего диспетчер кэша повторно отправляет запрос на чтение в виртуальную файловую систему для зашифрованного чтения.
В рамках фильтрации такую задачу решить невозможно в принципе.
При разработке виртуальной файловой системы мы столкнулись с некоторыми необычными проблемами.
Частично это связано с тем, что мы работаем с файлами файловой системы, тогда как обычные файловые системы работают с диском.
Например, обнаружена ошибка в файловой системе NTFS. Это проявлялось в том, что доступ к файлу X:\$mft\ привел к зависанию всего доступа к диску X. В результате исследования было установлено, что NTFS не реализовала механизмы синхронизации файла $mft, который является перечислителем всех файлов диска.
И соответственно, чтобы найти какой-либо файл на диске, сначала нужно прочитать файл $mft, доступ к которому приостановлен.
Другой пример, который не является чем-то необычным, — это ошибка, обнаруженная в ядре Windows 8, в результате которой диспетчер памяти предполагает, что структуры памяти файла всегда имеют последнюю версию.
Из-за этого он пытается использовать некоторые части этой структуры, которые на самом деле могут не существовать.
И это привело к BSOD. Реализация виртуальной файловой системы гораздо сложнее, чем реализация фильтра, но наличие такого механизма обеспечивает большую гибкость при манипулировании файлами.
В том числе и тот, о котором мы только что говорили.
Хотя на первый взгляд может показаться, что задача тривиальная.
В результате применения такого подхода к шифрованию успешно реализованы функции обеспечения одновременного доступа программных процессов к зашифрованному и расшифрованному контенту, а также шифрования имен файлов, что позволяет обеспечить высокую степень прозрачности при реализации криптографической защиты информации.
Следует отметить, что данный подход к обеспечению «прозрачности» шифрования файлов в ОС Windows успешно реализован в корпоративном продукте.
Секретное дисковое предприятие («Аладдин Р.
Д.
»), которым пользуются многие организации в России.
Это, в свою очередь, доказывает жизнеспособность и перспективность использования данной идеи в процессе создания программ для шифрования файлов на диске.
В качестве вывода стоит отметить, что технологическая сложность файловой системы ОС Windows и отсутствие стандартных механизмов решения задач, подобных описанным в данной статье, всегда будут препятствием на пути создания удобных и простых программ, обеспечивающих информационную безопасность.
защита.
В этом случае единственным правильным решением является самостоятельное внедрение оригинального механизма, позволяющего обойти эти ограничения без потери функциональности программного обеспечения.
Теги: #интеграция #шифрование #Windows #win32 #ntfs #BSOD #Высокая производительность #информационная безопасность #Криптография #Системное программирование
-
Нобелевская Премия По Физике
19 Oct, 24 -
Гараж48 Впервые В Киеве!
19 Oct, 24 -
Радио-У №66
19 Oct, 24