Наличие доверенной среды выполнения (TEE) в системе на кристалле (SoC) дает возможность устройствам Android предоставлять аппаратно-поддерживаемые, надежные службы безопасности для ОС Android, служб платформы и даже сторонних приложений (в виде специфичных для Android расширений стандартной архитектуры криптографии Java, см. KeyGenParameterSpec
).
Глоссарий
Ниже представлен краткий обзор компонентов Keystore и их взаимосвязей.
-
AndroidKeyStore
- API Android Framework и компонент, используемые приложениями для доступа к функционалу хранилища ключей. Это реализация стандартных API криптографической архитектуры Java, которая также добавляет расширения, специфичные для Android, и состоит из кода Java, который выполняется в пространстве собственных процессов приложения.
AndroidKeyStore
обрабатывает запросы приложения на работу с хранилищем ключей, перенаправляя их демону хранилища ключей. - демон хранилища ключей
- Системный демон Android, предоставляющий доступ ко всем функциям хранилища ключей через API Binder . Этот демон отвечает за хранение ключевых блоков, созданных базовой реализацией KeyMint (или Keymaster), которые содержат секретный ключевой материал в зашифрованном виде, что позволяет хранилищу ключей хранить их, но не использовать и не раскрывать.
- Служба KeyMint HAL
- Сервер AIDL, реализующий HAL
IKeyMintDevice
, предоставляющий доступ к базовому TA KeyMint. - Доверенное приложение KeyMint (TA)
- Программное обеспечение, работающее в безопасном контексте, чаще всего в TrustZone на базе ARM SoC, обеспечивает все безопасные криптографические операции. Это приложение имеет доступ к исходным данным ключей и проверяет все условия контроля доступа к ключам, прежде чем разрешить их использование.
-
LockSettingsService
- Компонент системы Android, отвечающий за аутентификацию пользователя по паролю и отпечатку пальца. Он не является частью Keystore, но важен, поскольку Keystore поддерживает концепцию привязанных ключей аутентификации : ключей, которые могут быть использованы только после аутентификации пользователя.
LockSettingsService
взаимодействует с Gatekeeper TA и Fingerprint TA для получения токенов аутентификации, которые он предоставляет демону хранилища ключей и которые используются KeyMint TA. - Привратник ТА
- Компонент, работающий в защищенной среде, который отвечает за аутентификацию паролей пользователей и генерацию токенов аутентификации, используемых для подтверждения ТА KeyMint того, что аутентификация была выполнена для конкретного пользователя в определенный момент времени.
- ТА по отпечаткам пальцев
- Компонент, работающий в защищенной среде, который отвечает за аутентификацию отпечатков пальцев пользователя и генерацию токенов аутентификации, используемых для подтверждения ТА KeyMint того, что аутентификация была выполнена для конкретного пользователя в определенный момент времени.
Архитектура
API хранилища ключей Android и лежащий в его основе KeyMint HAL предоставляют базовый, но достаточный набор криптографических примитивов, позволяющий реализовывать протоколы с использованием аппаратно поддерживаемых ключей с контролируемым доступом.
KeyMint HAL — это предоставляемая OEM-производителем служба, используемая службой Keystore для предоставления аппаратно-поддерживаемых криптографических сервисов. Для обеспечения безопасности данных закрытого ключа реализации HAL не выполняют никаких конфиденциальных операций ни в пространстве пользователя, ни даже в пространстве ядра. Вместо этого служба KeyMint HAL, работающая в Android, делегирует конфиденциальные операции TA, работающему в какой-либо безопасной среде, обычно путём маршаллинга и демаршаллинга запросов в формате, определяемом реализацией.
Итоговая архитектура выглядит так:

Рисунок 1. Доступ к KeyMint.
API KeyMint HAL — низкоуровневый интерфейс, используемый внутренними компонентами платформы и недоступный разработчикам приложений. Более высокоуровневый API Java, доступный приложениям, описан на сайте для разработчиков Android .
Контроль доступа
Хранилище ключей Android представляет собой центральный компонент для хранения и использования аппаратных криптографических ключей как для приложений, так и для других компонентов системы. Таким образом, доступ к любому отдельному ключу обычно ограничен приложением или компонентом системы, создавшим этот ключ.
Домены хранилища ключей
Для поддержки такого контроля доступа ключи идентифицируются в хранилище ключей с помощью дескриптора ключа . Этот дескриптор указывает домен , к которому принадлежит дескриптор, а также идентификатор в этом домене.
Приложения Android обращаются к Keystore, используя стандартную архитектуру криптографии Java, которая идентифицирует ключи по строковому псевдониму. Этот метод идентификации внутренне сопоставляется с доменом APP
Keystore; также включается UID вызывающего объекта для устранения неоднозначности ключей из разных приложений, предотвращая доступ одного приложения к ключам другого.
Внутри фреймворка код также получает уникальный числовой идентификатор ключа после его загрузки. Этот числовой идентификатор используется в качестве идентификатора для дескрипторов ключей в домене KEY_ID
. Однако контроль доступа по-прежнему осуществляется: даже если одно приложение обнаружит идентификатор ключа другого приложения, оно не сможет использовать его в обычных условиях.
Однако приложение может предоставить доступ к ключу другому приложению (идентифицируемому по UID). Эта операция предоставления доступа возвращает уникальный идентификатор, который используется в качестве идентификатора для дескрипторов ключей в домене GRANT
. Контроль доступа по-прежнему осуществляется: даже если третье приложение обнаружит идентификатор ключа получателя, оно не сможет его использовать.
Хранилище ключей также поддерживает два других домена для дескрипторов ключей, которые используются для других компонентов системы и недоступны для ключей, созданных приложением:
- Домен
BLOB
указывает на отсутствие идентификатора ключа в дескрипторе ключа; вместо этого дескриптор ключа содержит сам ключевой блок, а клиент управляет его хранением. Это используется клиентами (например,vold
), которым требуется доступ к хранилищу ключей до монтирования раздела данных. - Домен
SELINUX
позволяет системным компонентам совместно использовать ключи, при этом доступ регулируется числовым идентификатором, соответствующим метке SELinux (см. политику SELinux для keystore_key ).
Политика SELinux для keystore_key
Значения идентификаторов, используемые для дескрипторов ключей Domain::SELINUX
, настраиваются в файле политики SELinux keystore2_key_context
. Каждая строка в этих файлах сопоставляет числовое значение с меткой SELinux, например:
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share Keystore keys. 102 u:object_r:wifi_key:s0
Компонент, которому необходим доступ к ключу с идентификатором 102 в домене SELINUX
, должен иметь соответствующую политику SELinux. Например, чтобы разрешить wpa_supplicant
получать и использовать эти ключи, добавьте следующую строку в hal_wifi_supplicant.te
:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
Числовые идентификаторы ключей Domain::SELINUX
разделены на диапазоны для поддержки различных разделов без коллизий:
Раздел | Диапазон | Файлы конфигурации |
---|---|---|
Система | 0 ... 9,999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts |
Расширенная система | 10 000 ... 19 999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts |
Продукт | 20 000 ... 29 999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts |
Продавец | 30 000 ... 39 999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts |
Для системного раздела определены следующие конкретные значения:
Идентификатор пространства имен | Метка SEPolicy | UID | Описание |
---|---|---|---|
0 | su_key | Н/Д | Ключ суперпользователя. Используется только для тестирования сборок userdebug и eng. Не применимо к пользовательским сборкам. |
1 | shell_key | Н/Д | Пространство имён, доступное для оболочки. В основном используется для тестирования, но может использоваться и в пользовательских сборках из командной строки. |
100 | vold_key | Н/Д | Предназначено для использования vold. |
101 | odsign_key | Н/Д | Используется демоном подписи на устройстве. |
102 | wifi_key | AID_WIFI(1010) | Используется подсистемой Wi-Fi Android, включая wpa_supplicant . |
103 | locksettings_key | Н/Д | Используется LockSettingsService |
120 | resume_on_reboot_key | AID_SYSTEM(1000) | Используется системным сервером Android для поддержки возобновления работы после перезагрузки. |
Векторы доступа
Хранилище ключей позволяет контролировать, какие операции можно выполнять с ключом, а также контролировать общий доступ к ключу. Разрешения keystore2_key
описаны в файле KeyPermission.aidl
.
Системные разрешения
Помимо управления доступом на уровне ключа, описанного в политике SELinux для keystore_key , в следующей таблице описываются другие разрешения SELinux, необходимые для выполнения различных системных операций и операций по обслуживанию:
Разрешение | Значение |
---|---|
add_auth | Требуется для добавления токенов аутентификации в хранилище ключей; используется поставщиками аутентификации, такими как Gatekeeper или BiometricManager . |
clear_ns | Требуется для удаления всех ключей в определенном пространстве имен; используется в качестве операции обслуживания при удалении приложений. |
list | Требуется системой для перечисления ключей по различным свойствам, таким как владение или привязка к аутентификации. Это разрешение не требуется вызывающим объектам, перечисляющим свои собственные пространства имён (охватывается разрешением get_info ). |
lock | Требуется для уведомления хранилища ключей о том, что устройство заблокировано, что, в свою очередь, исключает суперключи, обеспечивая недоступность ключей аутентификации. |
unlock | Требуется для уведомления хранилища ключей о том, что устройство разблокировано, восстанавливая доступ к суперключам, которые защищают ключи, связанные с аутентификацией. |
reset | Требуется для сброса хранилища ключей к заводским настройкам, удаления всех ключей, которые не являются жизненно важными для функционирования ОС Android. |
История
В Android 5 и более ранних версиях Android имелся простой аппаратный API криптографических сервисов, предоставляемый аппаратным уровнем абстракции Keymaster (HAL) версий 0.2 и 0.3. Keystore обеспечивал операции цифровой подписи и верификации, а также генерацию и импорт пар асимметричных ключей подписи. Это уже реализовано на многих устройствах, но существует множество задач безопасности, которые невозможно легко решить с помощью одного лишь API подписи. В Android 6.0 API Keystore был расширен, предоставляя более широкий спектр возможностей.
Андроид 6.0
В Android 6.0 в Keymaster 1.0 были добавлены симметричные криптографические примитивы , AES и HMAC, а также система контроля доступа для аппаратных ключей. Контроль доступа задаётся при генерации ключа и применяется в течение всего срока его действия. Ключи можно ограничить так, чтобы они были доступны только после аутентификации пользователя и только для определённых целей или с определёнными криптографическими параметрами.
Помимо расширения спектра криптографических примитивов, Keystore в Android 6.0 добавил следующее:
- Схема контроля использования, позволяющая ограничить использование ключей, чтобы снизить риск нарушения безопасности из-за неправильного использования ключей.
- Схема контроля доступа, позволяющая ограничить доступ к ключам определенным пользователям, клиентам и определенному временному диапазону.
Андроид 7.0
В Android 7.0 в Keymaster 2 добавлена поддержка аттестации ключей и привязки версии.
Аттестация ключей обеспечивает выдачу сертификатов открытых ключей, содержащих подробное описание ключа и элементов управления доступом к нему, что позволяет удаленно проверить наличие ключа в защищенном оборудовании и его конфигурацию.
Привязка к версии привязывает ключи к версии операционной системы и уровню исправления. Это гарантирует, что злоумышленник, обнаружив уязвимость в старой версии системы или программного обеспечения TEE, не сможет откатить устройство к уязвимой версии и использовать ключи, созданные в новой версии. Кроме того, когда ключ с заданной версией и уровнем исправления используется на устройстве, обновлённом до новой версии или уровня исправления, ключ обновляется до того, как его можно будет использовать, а предыдущая версия ключа становится недействительной. По мере обновления устройства ключи перемещаются вперёд вместе с устройством, но любой возврат устройства к предыдущей версии делает ключи непригодными для использования.
Андроид 8.0
В Android 8.0 Keymaster 3 перешёл со старой структуры HAL на языке C на интерфейс HAL на языке C++, сгенерированный на основе определения на новом языке определения аппаратных интерфейсов (HIDL). В рамках этого изменения многие типы аргументов были изменены, хотя типы и методы имеют однозначное соответствие со старыми типами и методами структуры HAL.
Помимо этой версии интерфейса, Android 8.0 расширил функцию аттестации Keymaster 2, добавив поддержку аттестации ID . Аттестация ID предоставляет ограниченный и необязательный механизм для строгой аттестации идентификаторов оборудования, таких как серийный номер устройства, название продукта и идентификатор телефона (IMEI или MEID). Для реализации этого нововведения Android 8.0 изменил схему аттестации ASN.1, добавив аттестацию ID. Реализациям Keymaster необходимо найти безопасный способ извлечения соответствующих элементов данных, а также определить механизм для безопасного и постоянного отключения этой функции.
Андроид 9
В Android 9 обновления включали:
- Обновление до Keymaster 4
- Поддержка встроенных безопасных элементов
- Поддержка безопасного импорта ключей
- Поддержка шифрования 3DES
- Изменения в привязке версий, чтобы
boot.img
иsystem.img
имели отдельные установленные версии для обеспечения независимых обновлений.
Андроид 10
В Android 10 появилась версия Keymaster HAL 4.1, в которой добавлено:
- Поддержка ключей, которые можно использовать только при разблокированном устройстве
- Поддержка ключей, которые можно использовать только на ранних этапах загрузки
- Дополнительная поддержка аппаратно упакованных ключей хранения
- Дополнительная поддержка уникальной аттестации устройства в StrongBox
Андроид 12
В Android 12 появился новый KeyMint HAL, который заменяет Keymaster HAL, но обеспечивает схожую функциональность. Помимо всех вышеперечисленных функций, KeyMint HAL также включает в себя:
- Поддержка ключевого соглашения ECDH
- Поддержка пользовательских ключей аттестации
- Поддержка ключей с ограниченным количеством использований
Android 12 также включает новую версию демона системы хранилища ключей, переписанную на Rust и известную как keystore2
Андроид 13
В Android 13 добавлена версия KeyMint HAL v2, которая добавляет поддержку Curve25519 как для подписи, так и для согласования ключей.