Наличие доверенной среды выполнения в системе на кристалле (SoC) дает возможность устройствам Android предоставлять аппаратно-поддержанные, надежные службы безопасности для ОС Android, служб платформы и даже сторонних приложений (в виде специфичных для Android расширений стандартной архитектуры криптографии Java, см. KeyGenParameterSpec
).
Глоссарий
Ниже представлен краткий обзор компонентов хранилища ключей и их взаимосвязей.
-
AndroidKeyStore
- API Android Framework и компонент, используемый приложениями для доступа к функциональным возможностям Keystore. Это реализация стандартных API Java Cryptography Architecture, но также добавляет специфичные для Android расширения и состоит из кода Java, который выполняется в собственном пространстве процесса приложения.
AndroidKeyStore
выполняет запросы приложения на поведение Keystore, перенаправляя их демону keystore. - демон хранилища ключей
- Системный демон Android, который обеспечивает доступ ко всем функциям Keystore через API Binder . Этот демон отвечает за хранение keyblobs , созданных базовой реализацией KeyMint (или Keymaster), которые содержат секретный ключевой материал, зашифрованный, чтобы Keystore мог хранить их, но не использовать или раскрывать.
- Служба 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.
KeyMint HAL API — это низкоуровневый интерфейс, используемый внутренними компонентами платформы и не предоставляемый разработчикам приложений. Более высокоуровневый Java API, доступный приложениям, описан на сайте Android Developer .
Контроль доступа
Android Keystore предоставляет центральный компонент для хранения и использования аппаратно-поддерживаемых криптографических ключей как для приложений, так и для других компонентов системы. Таким образом, доступ к любому индивидуальному ключу обычно ограничен приложением или компонентом системы, создавшим ключ.
Домены хранилища ключей
Для поддержки этого контроля доступа ключи идентифицируются в Keystore с помощью дескриптора ключа . Этот дескриптор ключа указывает домен , к которому принадлежит дескриптор, вместе с идентификатором в этом домене.
Приложения Android получают доступ к Keystore, используя стандартную архитектуру Java Cryptography Architecture, которая идентифицирует ключи с помощью строкового псевдонима. Этот метод идентификации внутренне сопоставляется с доменом Keystore APP
; UID вызывающего также включается для устранения неоднозначности ключей из разных приложений, предотвращая доступ одного приложения к ключам другого.
Внутри код фреймворка также получает уникальный числовой идентификатор ключа после загрузки ключа. Этот числовой идентификатор используется в качестве идентификатора для дескрипторов ключей в домене KEY_ID
. Однако контроль доступа все равно выполняется: даже если одно приложение обнаруживает идентификатор ключа для ключа другого приложения, оно не может использовать его в обычных обстоятельствах.
Однако приложение может предоставить использование ключа другому приложению (идентифицируемому по UID). Эта операция предоставления возвращает уникальный идентификатор предоставления, который используется в качестве идентификатора для дескрипторов ключей в домене GRANT
. Опять же, контроль доступа по-прежнему выполняется: даже если третье приложение обнаружит идентификатор предоставления для ключа получателя, оно не сможет его использовать.
Хранилище ключей также поддерживает два других домена для дескрипторов ключей, которые используются для других компонентов системы и недоступны для ключей, созданных приложением:
- Домен
BLOB
указывает, что в дескрипторе ключа нет идентификатора для ключа; вместо этого дескриптор ключа содержит сам keyblob, а клиент управляет хранилищем keyblob. Это используется клиентами (например,vold
), которым необходимо получить доступ к Keystore до монтирования раздела данных. - Домен
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 ... 9999 | /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 | УИД | Описание |
---|---|---|---|
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 для поддержки возобновления работы после перезагрузки. |
Векторы доступа
Keystore позволяет контролировать, какие операции могут быть выполнены с ключом, в дополнение к контролю общего доступа к ключу. Разрешения 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 криптографических служб с аппаратной поддержкой, предоставляемый версиями 0.2 и 0.3 уровня аппаратной абстракции Keymaster (HAL). 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 перешел от старого стиля C-структуры HAL к интерфейсу C++ HAL, сгенерированному из определения на новом языке определения аппаратного интерфейса (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 как для подписи, так и для согласования ключей.