[Перевод] Intel Software Guard Extensions, учебное руководство. Часть 2, устройство приложения
Прочтите первую часть или список всех опубликованных учебных материалов в статье Представляем серию учебных материалов, посвященных Intel Software Guard Extensions.
Диспетчеры паролей — краткое описание
Пользователи, как правило, знают, что такое диспетчеры паролей и для чего они служат, но всегда полезно еще раз пройтись по общей информации перед тем, как заниматься подробностями устройства приложения.
Основные цели диспетчера паролей:
- Сокращение количества паролей, которые необходимо запоминать пользователю.
- Предоставление конечным пользователям возможности создавать более стойкие пароли, чем они смогли бы придумать самостоятельно.
- Повысить удобство использования разных паролей у каждой учетной записи.
Управление паролями — актуальная проблема для пользователей Интернета, и за несколько лет было предпринято несколько исследований, направленных на решение этой проблемы. В исследовании корпорации Майкрософт, опубликованном в 2007 году, — почти десять лет назад — указано, что у каждого пользователя было в среднем 25 учетных записей, для которых требовались пароли. Позже, в 2014 году, специалисты компании Dashlane подсчитали, что у их пользователей в США было в среднем по 130 учетных записей, а среднее количество учетных записей на каждого пользователя во всем мире составило около 90. Впрочем, на этом проблемы не кончаются: люди, как правило, крайне редко выбирают стойкие пароли, часто используют один и тот же пароль на множестве сайтов, что послужило причиной скандальных атак злоумышленников. Все эти проблемы обусловлены всего двумя основными факторами: во-первых, людям зачастую трудно запомнить стойкие пароли, устойчивые к взлому; во-вторых, если использовать не один пароль, а множество, то ситуация становится еще сложнее, поскольку теперь помимо собственно паролей необходимо также помнить, с какой учетной записью связан каждый пароль.
При использовании диспетчера паролей достаточно запомнить всего одну очень стойкую парольную фразу, чтобы получить доступ к базе данных паролей (хранилищу паролей). После входа в диспетчер паролей можно найти все сохраненные там пароли, скопировать и вставить их в поля проверки подлинности на нужных сайтах. Разумеется, главным уязвимым местом диспетчера паролей является база данных паролей: это излюбленная мишень злоумышленников, поскольку в ней хранятся все пароли пользователя. Поэтому база данных паролей шифруется с помощью стойких алгоритмов шифрования, а для расшифровки содержащихся в них данных используется главная парольная фраза пользователя.
Наша цель в этом учебном руководстве — создать простой диспетчер паролей, предоставляющий те же основные функции, что и аналогичные коммерческие продукты, соблюдая при этом рекомендации в области безопасности и используя эту программу в качестве упражнения, чтобы изучить Intel SGX. Этот учебный диспетчер паролей я решил назвать «Tutorial Password Manager с Intel Software Guard Extensions» (да, произнести непросто, зато название говорит само за себя). Эта программа не предназначена для использования в качестве коммерческого продукта и, безусловно, не будет содержать всех защитных механизмов, свойственных коммерческим решениям, но для обучения такой уровень подробностей и не требуется.
Базовые требования к приложению
Базовые требования к приложению помогут ограничить область приложения, чтобы можно было сосредоточиться на интеграции Intel SGX, а не на тонкостях проектирования и разработки приложения. Напомню, перед нами не стоит задача создания коммерческого продукта: от программы Tutorial Password Manager с Intel SGX не требуется возможности запуска в множестве операционных систем или на всех возможных архитектурах ЦП. Требуется лишь некая действующая отправная точка.
Поэтому базовые требования к приложению таковы:
Требования к решению и принципам работы |
|
Первое требование может показаться странным, если учесть, что эта серия учебных материалов посвящена разработке приложений, использующих Intel SGX, но приложения, предназначенные для реального мира, должны предусматривать возможность установки на устаревших системах. Для некоторых приложений может быть целесообразно разрешить выполнение только на платформах, поддерживающих Intel SGX, но в Tutorial Password Manager мы выбрали более гибкий подход. Платформа, поддерживающая Intel SGX, получит более защищенную среду выполнения, но и на других платформах программа все равно будет работать. Такая модель использования вполне подходит для диспетчера паролей, поскольку пользователи могут синхронизировать свои пароли с другими, более старыми системами. Кроме того, это возможность научиться реализации двойных ветвей кода.
Второе требование предоставляет нам доступ к определенным алгоритмам шифрования в ветви кода без поддержки Intel SGX и к некоторым библиотекам, которые нам потребуются. Требование использования 64-разрядной операционной системы упрощает разработку приложения за счет доступа к 64-разрядным типам собственного кода. Кроме того, повышается скорость работы некоторых алгоритмов шифрования, оптимизированных для 64-разрядного кода.
Третье требование предоставляет нам доступ к инструкции RDRAND в ветви кода без поддержки Intel SGX. Это существенно упрощает генерацию случайных чисел и обеспечивает доступ к источнику с высокой энтропией. Системы, поддерживающие инструкцию RDSEED, смогут использовать ее. (Сведения об инструкциях RDRAND и RDSEED см. в руководстве по внедрению программного обеспечения генерации случайных чисел Intel).
Четвертое требование поддерживает наивозможную краткость списка программного обеспечения, требуемого разработчику (и пользователю). Не требуется загружать и устанавливать никакие сторонние библиотеки, платформы, приложения и служебные программы. Впрочем, у этого требования есть не слишком приятный побочный эффект: если отказаться от сторонних платформ, то у нас остается всего четыре варианта создания пользовательского интерфейса. Вот эти варианты:
- API-интерфейсы Win32
- Microsoft Foundation Classes (MFC)
- Windows Presentation Foundation (WPF)
- Windows Forms
Первые два варианта реализуются с помощью собственного/неуправляемого кода, а для двух последних вариантов требуется .NET*.
Платформа пользовательского интерфейса
Мы разработаем графический пользовательский интерфейс для программы Tutorial Password Manager с помощью Windows Presentation Foundation на языке C#. Это решение следующим образом повлияет на наши требования:
Требования к решению и принципам работы |
|
Почему решено использовать WPF? Главным образом из-за того, что при этом упрощается проектирование пользовательского интерфейса и привносится нужный нам уровень сложности. В частности, поскольку интерфейс опирается на .NET Framework, мы получаем возможность обсудить смешение управляемого кода и, в частности, высокоуровневых языков с кодом анклава. Обратите внимание, что выбор WPF вместо Windows Forms был совершенно произвольным: наша среда работала бы и в том, и в другом случае.
Как вы, возможно, помните, анклавы должны быть написаны на собственном коде C или C++, а функции моста, взаимодействующего с анклавом, должны быть собственными функциями языка C (но не C++). И API-интерфейсы Win32, и MFC дают возможность разработки диспетчера паролей, используя полностью собственный код C/C++, но задачи по разработке, связанные с этими двумя методами, бесполезны для разработчиков, стремящихся изучить разработку приложений, использующих Intel SGX. Используя графический пользовательский интерфейс на основе управляемого кода, мы получим не только преимущества интегрированных средств разработки, но и возможность обсудить определенные вопросы, полезные для разработчиков приложений Intel SGX. Коротко говоря, вы здесь не для того, чтобы научиться использовать MFC или Win32, но вас может заинтересовать, как соединить .NET с анклавами.
Для связывания управляемого и неуправляемого кода мы будем использовать C++/CLI (то есть C++, измененный для Common Language Infrastructure). Это существенно упрощает упаковку данных и настолько удобно, что многие разработчики называют этот метод «IJW» (It Just Works — это просто работает).
Рисунок 1. Минимальные структуры компонентов приложений Intel Software Guard Extensions для собственного кода и C#.
На рис. 1 показано влияние на минимальный состав компонентов приложения Intel SGX при переходе от собственного кода к C#. При использовании только собственного кода уровень приложения может напрямую взаимодействовать с DLL-библиотекой анклава, поскольку функции моста анклава можно встроить в исполняемый файл приложения. В смешанном приложении функции моста анклава потребуется выделить из блока управляемого кода, поскольку эти функции должны быть полностью собственным кодом. С другой стороны, приложение C# не может напрямую взаимодействовать с функциями моста, а в модели C++/CLI это означает, что нужно создать еще один промежуточный уровень: DLL-библиотеку, которая передает данные между управляемым приложением C# и DLL-библиотекой моста анклава, состоящей только из собственного кода.
Требования к хранилищу паролей
В основе диспетчера паролей находится база данных паролей, которую мы также будем называть хранилищем паролей. Это зашифрованный файл, в котором будет содержаться информация об учетных записях и паролях конечного пользователя. Основные требования к нашему учебному приложению таковы:
Требования к решению и принципам работы |
|
Требование переносимости хранилища означает, что у нас должна быть возможность скопировать файл хранилища на другой компьютер и по-прежнему получить доступ к его содержимому независимо от того, поддерживает ли другой компьютер расширения Intel SGX. Другими словами, возможности пользователей должны быть одинаковыми: диспетчер паролей должен работать на любом компьютере (естественно, если оборудование и ОС соответствуют указанным требованиям к системе).
Шифрование хранилища при хранении означает, что файл хранилища должен быть зашифрован, когда он не находится в активном использовании. При этом хранилище должно быть зашифровано на диске (если бы не было требования переносимости, то требование шифрования можно было бы решить, используя функцию запечатывания в Intel SGX), и не должно находиться в расшифрованном виде в оперативной памяти дольше, чем необходимо.
Шифрование с проверкой подлинности гарантирует, что зашифрованное хранилище не было изменено после шифрования. Также благодаря этому мы получаем удобное средство проверки парольной фразы пользователя: если ключ расшифровки неверный, расшифровка выдаст отказ при проверке тега подлинности. В этом случае нам нет необходимости изучать расшифрованные данные, чтобы убедиться в их правильности.
Пароли
Любая информация учетных записей является конфиденциальной по разным причинам, и не в последнюю очередь информация о том, на какие учетные записи и сайты можно направлять атаку, но пароли, пожалуй, являются самой важной информацией в хранилище. Знать, что именно нужно атаковать, конечно, хорошо, но если знать пароли, то атаковать вообще не потребуется, что гораздо лучше. Поэтому мы вводим дополнительные требования для паролей, находящихся в хранилище:
Требования к решению и принципам работы |
|
Это вложенное многоуровневое шифрование. Пароли всех учетных записей пользователя шифруются при помещении в хранилище, и само хранилище шифруется при записи на диск. Такой подход позволяет снизить уязвимость паролей после расшифровки хранилища. Целесообразно расшифровывать хранилище целиком, чтобы пользователь мог просматривать все свои учетные данные, но отображение всех паролей обычным текстом вряд ли допустимо.
Пароль учетной записи расшифровывается лишь в случае, когда пользователь этого требует. Благодаря этому ограничивается уязвимость пароля в оперативной памяти и на экране.
Алгоритмы шифрования
Поскольку наши требования к шифрованию уже определены, пора выбрать определенные алгоритмы шифрования, и в этом отношении существующие требования к нашему приложению существенно ограничивают доступные варианты. Программа Tutorial Password Manager должна работать как на платформах, поддерживающих Intel SGX, так и без Intel SGX, при этом запрещено использовать сторонние библиотеки. Это означает, что необходимо выбрать алгоритм, размер ключа и размер тега подлинности, поддерживаемые и в API Windows CNG, и в доверенной библиотеке шифрования Intel SGX. На практике это означает, что в нашем распоряжении остается один-единственный возможный алгоритм: AES-GCM с 128-разрядным ключом. Это, пожалуй, не самый лучший режим шифрования для использования в приложении, особенно поскольку эффективная стойкость тега подлинности 128-разрядного GCM меньше 128 бит, но для наших целей этого будет достаточно. Помните: наша задача — создание не коммерческого продукта, а учебного пособия по использованию Intel SGX.
Выбор GCM влияет на другие характеристики шифрования в нашем приложении, в частности, на длину вектора инициализации (12 байт — оптимальное значение для этого алгоритма) и тега подлинности.
Требования к решению и принципам работы |
|
Ключи шифрования и проверка подлинности пользователей
После выбора алгоритма шифрования можно перейти к ключу шифрования и проверки подлинности пользователей. Как пользователь проходит проверку подлинности в диспетчере паролей, чтобы открыть свое хранилище?
Самый простой способ — формировать ключ шифрования напрямую из парольной фразы или пароля пользователя, используя функцию формирования ключа (KDF). Этот простой подход вполне работоспособен, но у него есть один существенный недостаток: если пользователь сменит пароль, то вместе с ним изменится и ключ шифрования. Вместо этого мы применим более распространенный подход и зашифруем ключ шифрования.
В этом случае первичный ключ шифрования формируется случайным образом на основе источника с высокой энтропией и никогда не меняется. Парольная фраза или пароль пользователя используется для формирования вторичного ключа шифрования, и этот вторичный ключ используется, чтобы зашифровать первичный ключ. У этого подхода есть ряд важных преимуществ:
- Данные не придется повторно шифровать при изменении пароля или парольной фразы пользователя.
- Ключ шифрования никогда не изменяется, поэтому его можно, к примеру, записать на бумаге в шестнадцатеричном формате и хранить в физически безопасном месте. В этом случае данные можно будет расшифровать даже в случае, если пользователь забудет пароль. Поскольку ключ никогда не изменяется, его достаточно записать только один раз.
- Теоретически можно предоставлять доступ к данным нескольким пользователям. Каждый пользователь зашифрует копию первичного ключа своей собственной парольной фразой.
Не все эти возможности важны для Tutorial Password Manager, но это разумная практика безопасности.
Требования к решению и принципам работы |
|
Здесь первичный ключ называется ключом хранилища, а вторичный ключ, формируемый из парольной фразы пользователя, называется главным ключом. Пользователь проходит проверку подлинности, вводя свою парольную фразу, а диспетчер паролей формирует из нее главный ключ. Если главный ключ успешно расшифрует ключ хранилища, то пользователь проходит проверку и можно расшифровать хранилище. Если парольная фраза неверна, расшифровка ключа хранилища невозможна, что не позволяет расшифровать хранилище.
Последнее требование, касающееся создания функции формирования ключа на основе алгоритма SHA-256, обусловлено ограничением, проистекающим из необходимости использовать алгоритм хэширования, который поддерживается и в API Windows CNG, и в библиотеке шифрования Intel SGX.
Сведения учетной записи
Последнее из основных требований касается того, что именно помещается в хранилище. В этом учебном руководстве мы пойдем по простому пути. На рис. 2 показан макет главного окна пользовательского интерфейса.
Требования к решению и принципам работы |
|
Рисунок 2. Предварительный макет главного окна Tutorial Password Manager.
Последнее требование посвящено упрощению кода. Если зафиксировать количество учетных записей, находящихся в хранилище, можно легче определить верхнюю границу размера хранилища. Это будет важно при проектировании анклава. Разумеется, настоящие диспетчеры паролей лишены такой роскоши, но в учебном руководстве мы вполне можем себе это позволить.
В дальнейших выпусках
В третьей части этого учебного руководства мы подробнее рассмотрим устройство приложения Tutorial Password Manager для Intel SGX. Мы определим секреты, решим, какие части приложения должны находиться внутри анклава, каким образом анклав будет взаимодействовать с основным приложением и как анклав влияет на объектную модель. Следите за новостями!
Прочтите первую часть учебного руководства этой серии, Расширения Intel Software Guard Extensions > Учебное руководство: часть 1, Intel SGX Foundation, или список всех опубликованных учебных материалов в статье Представляем серию учебных материалов, посвященных Intel Software Guard Extensions.