Функции

На этой странице содержится информация о криптографических функциях Android Keystore, которые предоставляются базовой реализацией KeyMint (или Keymaster).

Криптографические примитивы

В Keystore доступны следующие категории операций:

  • Создание ключей, в результате которого создаются закрытые или секретные ключи, доступные только в защищенной среде. Клиенты могут создавать ключи следующими способами:
    • Создание нового ключа
    • Импорт незашифрованного ключевого материала
    • Импорт зашифрованного материала ключа
  • Аттестация ключей. При создании асимметричного ключа генерируется сертификат, содержащий открытый ключ из пары. Этот сертификат также может содержать информацию о метаданных ключа и состоянии устройства, подписанную ключом, который связан с доверенным корневым сертификатом.
  • Криптографические операции:
    • Симметричное шифрование и расшифровка (AES, 3DES)
    • Асимметричная расшифровка (RSA)
    • Асимметричная подпись (ECDSA, RSA)
    • Симметричное подписание и проверка (HMAC)
    • Асимметричное согласование ключей (ECDH)

Элементы протокола, такие как назначение, режим и заполнение, а также ограничения контроля доступа, указываются при создании или импорте ключей и постоянно привязываются к ключу, что гарантирует, что ключ не может быть использован никаким другим способом.

Примитивы и режимы, которые должны поддерживаться реализацией KeyMint, описаны в спецификации интерфейса HAL IKeyMintDevice.

Базовая реализация KeyMint должна генерировать случайные числа для поддержки генерации ключей и создания рандомизированных векторов заполнения или инициализации (IV). Для этого система Android периодически предоставляет дополнительную энтропию реализации KeyMint.

Контроль доступа к ключам

Аппаратные ключи, которые невозможно извлечь из устройства, не обеспечивают достаточную безопасность, если злоумышленник может использовать их по своему усмотрению (хотя они более безопасны, чем ключи, которые можно извлечь). Поэтому важно, чтобы Keystore обеспечивал контроль доступа.

Контроль доступа определяется как "список авторизации" пар "тег/значение". Теги авторизации представляют собой 32-битные целые числа, а значения могут быть разных типов. Некоторые теги можно повторять, чтобы указать несколько значений. Возможность повторения тега указывается в интерфейсе HAL KeyMint (ранее Keymaster).

Допустимые значения тегов определены в файле Tag.aidl. Каждое из них связано с TagType, который указывает тип связанного значения (например, целое число или байты) и то, можно ли его повторить, чтобы указать несколько поддерживаемых значений.

Когда KeyMint создает ключ, вызывающий абонент указывает список авторизации для ключа. Этот список изменяется Keystore и KeyMint для добавления дополнительных ограничений, а базовая реализация KeyMint кодирует окончательный список авторизации в возвращаемый keyblob. Закодированный список авторизации криптографически связан с блоком ключей, поэтому любая попытка изменить список авторизации (включая порядок) приводит к созданию недействительного блока ключей, который нельзя использовать для криптографических операций.

Аппаратные и программные меры

Не все реализации защищенного оборудования содержат одинаковые функции. Чтобы поддерживать различные подходы, KeyMint различает безопасное и небезопасное применение контроля доступа, или аппаратное и программное применение соответственно.

Это отражено в KeyMint API в поле securityLevel типа KeyCharacteristics. Защищенное аппаратное обеспечение отвечает за размещение авторизаций в KeyCharacteristics с соответствующим уровнем безопасности, исходя из того, что оно может обеспечить. Эта информация также содержится в записях подтверждения для асимметричных ключей: характеристики ключей для SecurityLevel::TRUSTED_ENVIRONMENT или SecurityLevel::STRONGBOX указаны в списке hardwareEnforced, а характеристики для SecurityLevel::SOFTWARE или SecurityLevel::KEYSTORE – в списке softwareEnforced.

Например, ограничения на дату и время, когда можно использовать ключ, обычно не применяются защищенной средой, поскольку у нее нет надежного доступа к информации о дате и времени. В результате такие разрешения, как Tag::ORIGINATION_EXPIRE_DATETIME, применяются Keystore в Android и имеют SecurityLevel::KEYSTORE.

Подробнее о том, как определить, поддерживаются ли ключи и их авторизация аппаратным обеспечением, рассказывается в статье Аттестация ключей.

Разрешения на создание криптографических сообщений

Для определения криптографических характеристик операций с использованием связанного ключа используются следующие теги:

  • Tag::ALGORITHM
  • Tag::KEY_SIZE
  • Tag::BLOCK_MODE
  • Tag::PADDING
  • Tag::CALLER_NONCE
  • Tag::DIGEST
  • Tag::MGF_DIGEST

Следующие теги являются повторяемыми, то есть с одним ключом можно связать несколько значений:

  • Tag::BLOCK_MODE
  • Tag::PADDING
  • Tag::DIGEST
  • Tag::MGF_DIGEST

Значение, которое будет использоваться, указывается во время операции.

Назначение

С ключами связан набор целей, выраженных в виде одной или нескольких записей авторизации с тегом Tag::PURPOSE, который определяет, как их можно использовать. Цели определены в KeyPurpose.aidl.

Обратите внимание, что некоторые комбинации значений purpose могут привести к проблемам с безопасностью. Например, если ключ RSA можно использовать и для шифрования, и для подписи, злоумышленник, который может заставить систему расшифровать произвольные данные, сможет генерировать подписи.

Импорт ключей

KeyMint поддерживает импорт:

  • Асимметричные пары ключей в формате PKCS#8 с кодировкой DER (без шифрования на основе пароля).
  • Симметричные ключи в виде необработанных байтов

Чтобы импортированные ключи можно было отличить от сгенерированных безопасным способом, в соответствующий список авторизации ключей включается Tag::ORIGIN. Например, если ключ был сгенерирован в защищенном аппаратном обеспечении, то в списке характеристик ключа hw_enforced будет указан тег Tag::ORIGIN со значением KeyOrigin::GENERATED. Если же ключ был импортирован в защищенное аппаратное обеспечение, то значением будет KeyOrigin::IMPORTED.

Аутентификация пользователей

Безопасные реализации KeyMint не выполняют аутентификацию пользователей, а зависят от других доверенных приложений, которые это делают. Сведения об интерфейсе, который реализуют эти приложения, можно найти на странице Gatekeeper.

Требования к аутентификации пользователей задаются с помощью двух наборов тегов. Первый набор указывает, какие способы аутентификации разрешают использование ключа:

  • Tag::USER_SECURE_ID содержит 64-битное числовое значение, указывающее защищенный идентификатор пользователя, который предоставляется в токене защищенной аутентификации для разблокировки ключа. Если ключ повторяется, его можно использовать, если в токене безопасной аутентификации указано любое из значений.

Второй набор определяет, нужно ли пользователю проходить аутентификацию и когда. Если ни одного из этих тегов нет, но есть тег Tag::USER_SECURE_ID, аутентификация требуется при каждом использовании ключа.

  • Tag::NO_AUTHENTICATION_REQUIRED указывает, что аутентификация пользователя не требуется, хотя доступ к ключу по-прежнему ограничен приложением-владельцем (и любыми приложениями, которым оно предоставляет доступ).
  • Tag::AUTH_TIMEOUT – числовое значение, указывающее в секундах, насколько свежей должна быть аутентификация пользователя, чтобы разрешить использование ключа. При перезагрузке все аутентификации аннулируются. Для тайм-аута можно задать большое значение, чтобы аутентификация требовалась один раз за загрузку (2^32 секунды – это примерно 136 лет; предположительно, устройства Android перезагружаются чаще).

Требовать разблокировки устройства

Ключи со значком Tag::UNLOCKED_DEVICE_REQUIRED можно использовать, только когда устройство разблокировано. Подробную информацию о семантике можно найти в статье KeyProtection.Builder#setUnlockedDeviceRequired(boolean).

UNLOCKED_DEVICE_REQUIRED применяется Keystore, а не KeyMint. Однако в Android 12 и более поздних версиях Keystore криптографически защищает ключи UNLOCKED_DEVICE_REQUIRED, когда устройство заблокировано. Это гарантирует, что в большинстве случаев их нельзя будет использовать, даже если Keystore будет взломан, пока устройство заблокировано.

Все криптографические операции и генерация случайных чисел, описанные в этом разделе, выполняются с помощью BoringSSL, за исключением случаев, когда явно указано использование KeyMint. Все секреты обнуляются, как только они перестают быть нужны.

Суперключи UnlockedDeviceRequired

Чтобы защитить ключи UNLOCKED_DEVICE_REQUIRED с помощью криптографии, Keystore выполняет их супершифрование перед сохранением в базе данных. По возможности ключи супершифрования (суперключи) защищаются, пока устройство заблокировано, так, чтобы их можно было восстановить только после успешной разблокировки устройства. Термин "супершифрование" используется, потому что этот уровень шифрования применяется в дополнение к уровню шифрования, который KeyMint уже применяет ко всем ключам.

У каждого пользователя (включая профили) есть два суперключа, связанных с UNLOCKED_DEVICE_REQUIRED:

  • Симметричный суперключ UnlockedDeviceRequired. Это ключ AES‑256‑GCM. Оно шифрует ключи UNLOCKED_DEVICE_REQUIRED, которые импортируются, генерируются или используются, когда устройство разблокировано для пользователя.
  • Асимметричный суперключ UnlockedDeviceRequired. Это пара ключей ECDH P‑521. Оно шифрует UNLOCKED_DEVICE_REQUIRED ключей, которые импортируются или генерируются, пока устройство заблокировано для пользователя. Подробнее о том, как хранить ключи, когда устройство заблокировано…

Создание и защита суперключей

При создании пользователя Keystore генерирует суперключи UnlockedDeviceRequired и сохраняет их в своей базе данных, зашифровав (косвенно) синтетическим паролем пользователя.

  1. Сервер системы получает пароль пользователя от хранилища ключей из синтетического пароля пользователя с помощью функции формирования ключа SP800‑108.
  2. Системный сервер передает пароль пользователя в Keystore.
  3. Keystore генерирует суперключи пользователя.
  4. Для каждого суперключа пользователя:
    1. Keystore генерирует случайную соль.
    2. Keystore получает ключ AES-256-GCM из пароля Keystore пользователя и соли, используя HKDF-SHA256.
    3. Keystore шифрует секретную часть суперключа с помощью этого ключа AES-256-GCM.
    4. Keystore сохраняет зашифрованный суперключ и его соль в своей базе данных. Если это асимметричный ключ, то его открытая половина также хранится в незашифрованном виде.

Эта процедура позволяет расшифровать суперключи, когда известен синтетический пароль пользователя, например когда введен правильный PIN-код, графический ключ или пароль.

Keystore также кеширует эти суперключи в памяти, что позволяет ему работать с ключами UNLOCKED_DEVICE_REQUIRED. Однако он пытается кешировать секретные части этих ключей, только когда устройство разблокировано для пользователя. Когда устройство заблокировано, Keystore по возможности обнуляет кешированную копию секретных частей этих суперключей. В частности, когда устройство заблокировано, Keystore выбирает и применяет один из трех уровней защиты для суперключей UnlockedDeviceRequired:

  • Если у пользователя включен только PIN-код, графический ключ или пароль, Keystore обнуляет секретные части кешированных суперключей. Это делает суперключи восстанавливаемыми только через зашифрованную копию в базе данных, которую можно расшифровать только с помощью PIN-кода, графического ключа или эквивалента пароля.
  • Если у пользователя включены только биометрические данные класса 3 ("надежные") и PIN-код, графический ключ или пароль, Keystore позволяет восстановить суперключи с помощью любых зарегистрированных биометрических данных класса 3 (обычно это отпечаток пальца) в качестве альтернативы PIN-коду, графическому ключу или паролю. Для этого генерируется новый ключ AES-256-GCM, с помощью которого шифруются секретные части суперключей. Затем ключ AES-256-GCM импортируется в KeyMint как ключ, связанный с биометрическими данными и требующий успешной биометрической аутентификации в течение последних 15 секунд. После этого копии всех этих ключей в виде обычного текста обнуляются.
  • Если у пользователя включена биометрия класса 1 ("удобство"), биометрия класса 2 ("слабая") или активный агент доверия для разблокировки, Keystore хранит суперключи в кеше в виде обычного текста. В этом случае криптографическая защита ключей UNLOCKED_DEVICE_REQUIRED не обеспечивается. Чтобы избежать этого, не включайте такие способы разблокировки. Самые распространенные методы разблокировки, которые относятся к этим категориям, – это фейсконтроль на многих устройствах и разблокировка с помощью подключенных умных часов.

Когда пользователь разблокирует устройство, Keystore по возможности восстанавливает суперключи UnlockedDeviceRequired. Если вы используете PIN-код, графический ключ или пароль, то расшифровывается копия ключей, хранящаяся в базе данных. В противном случае проверяется, сохранена ли копия этих ключей, зашифрованная с помощью ключа, связанного с биометрическими данными. Если да, то выполняется попытка расшифровки. Это возможно, только если пользователь успешно прошел аутентификацию с помощью биометрических данных класса 3 в течение последних 15 секунд. Проверка выполняется KeyMint, а не Keystore.

Хранение ключей, когда устройство заблокировано

Keystore позволяет пользователям импортировать и генерировать ключи UNLOCKED_DEVICE_REQUIRED, когда устройство заблокировано. Для этого используется схема гибридного шифрования, которая гарантирует, что данные можно будет расшифровать только после разблокировки устройства.

  • Шифрование (импорт или создание ключа UNLOCKED_DEVICE_REQUIRED, когда устройство заблокировано):
    1. Keystore генерирует новую эфемерную пару ключей ECDH P-521.
    2. Keystore генерирует общий секретный ключ, выполняя согласование ключей ECDH между закрытым ключом этой эфемерной пары ключей и открытой половиной асимметричного суперключа UnlockedDeviceRequired.
    3. Keystore генерирует случайную соль.
    4. Keystore получает ключ AES-256-GCM из общего секрета и соли с помощью HKDF-SHA256.
    5. Keystore шифрует ключ UNLOCKED_DEVICE_REQUIRED с помощью этого ключа AES-256-GCM.
    6. Хранилище ключей сохраняет зашифрованный ключ UNLOCKED_DEVICE_REQUIRED, соль и открытую половину временной пары ключей в своей базе данных.
  • Расшифровка (с помощью созданного ключа UNLOCKED_DEVICE_REQUIRED, когда устройство разблокировано):
    1. Keystore загружает зашифрованный ключ UNLOCKED_DEVICE_REQUIRED, соль и открытую половину эфемерной пары ключей из своей базы данных.
    2. Keystore генерирует общий секретный ключ, выполняя согласование ключей ECDH между открытой половиной пары эфемерных ключей и закрытой половиной асимметричного суперключа UnlockedDeviceRequired. Закрытый ключ доступен, поскольку устройство разблокировано.
    3. Keystore получает ключ AES-256-GCM из общего секрета и соли с помощью HKDF-SHA256. Этот ключ AES‑256‑GCM совпадает с ключом, полученным во время шифрования.
    4. Keystore расшифровывает ключ UNLOCKED_DEVICE_REQUIRED с помощью ключа AES‑256‑GCM.
    5. Keystore повторно шифрует ключ UNLOCKED_DEVICE_REQUIRED, используя симметричный суперключ UnlockedDeviceRequired. Это не влияет на свойства безопасности ключа, но позволяет быстрее получить к нему доступ в дальнейшем.

Эта функция позволяет приложениям хранить данные, пока устройство заблокировано, и расшифровывать их только после разблокировки. Для этого в приложениях должны выполняться следующие действия:

  1. Сгенерируйте ключ AES‑256‑GCM вне Keystore.
  2. Зашифруйте данные с помощью ключа AES-256-GCM.
  3. Импортируйте ключ AES-256-GCM в Keystore с набором защиты ключей setUnlockedDeviceRequired(true).
  4. Обнулите оригинальную копию ключа.

Чтобы расшифровать данные, когда устройство разблокировано, используйте ключ, импортированный в Keystore.

Привязка клиента

Привязка клиента, то есть связывание ключа с определенным клиентским приложением, выполняется с помощью необязательного идентификатора клиента и необязательных данных клиента (Tag::APPLICATION_ID и Tag::APPLICATION_DATA соответственно). Keystore обрабатывает эти значения как непрозрачные большие двоичные объекты, гарантируя, что одни и те же объекты, представленные во время генерации/импорта ключа, будут представлены для каждого использования и будут идентичны побайтно. KeyMint не возвращает данные привязки клиента. Вызывающий абонент должен знать его, чтобы использовать ключ.

Эта функция недоступна приложениям.

Срок действия

Keystore поддерживает ограничение использования ключей по дате. С ключом можно связать начало и окончание срока его действия. Если текущая дата или время не попадают в этот диапазон, Keystore отказывается выполнять операции с ключом. Срок действия ключа задается тегами Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME и Tag::USAGE_EXPIRE_DATETIME. Различие между созданием и использованием основано на том, применяется ли ключ для создания нового зашифрованного текста, подписи и т. д. или для использования существующего зашифрованного текста, подписи и т. д. Обратите внимание, что это различие не показывается приложениям.

Теги Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME и Tag::USAGE_EXPIRE_DATETIME являются необязательными. Если теги отсутствуют, предполагается, что ключ можно использовать для расшифровки и проверки сообщений в любое время.

Поскольку время по часам предоставляется небезопасной средой, теги, связанные с истечением срока действия, находятся в списке, применяемом программным обеспечением.

Привязка корня доверия

Keystore требует, чтобы ключи были привязаны к корню доверия, который представляет собой битовую строку, предоставляемую защищенному оборудованию KeyMint во время запуска, предпочтительно загрузчиком операционной системы. Эта битовая строка криптографически связана с каждым ключом, управляемым KeyMint.

Корень доверия состоит из хеша открытого ключа, который используется для проверки подписи загрузочного образа, и состояния блокировки устройства. Если открытый ключ изменен, чтобы можно было использовать другой образ системы, или если изменено состояние блокировки, то ни один из ключей, защищенных KeyMint и созданных предыдущей системой, не будет работать, пока не будет восстановлен предыдущий корень доверия и не будет загружена система, подписанная этим ключом. Цель – повысить ценность программных средств контроля доступа к ключам, сделав невозможным использование ключей KeyMint операционной системой, установленной злоумышленником.

Повторная инициализация генератора случайных чисел

Поскольку защищенное аппаратное обеспечение генерирует случайные числа для материала ключа и векторов инициализации (IV), а аппаратные генераторы случайных чисел не всегда могут быть полностью надежными, KeyMint HAL предоставляет интерфейс, позволяющий Keystore обеспечивать дополнительную энтропию, которая смешивается со сгенерированными случайными числами.

Используйте аппаратный генератор случайных чисел в качестве основного источника начальных значений. Исходные данные, полученные через внешний API, не могут быть единственным источником случайности, используемым для генерации чисел. Кроме того, используемая операция смешивания должна гарантировать, что случайный вывод будет непредсказуемым, если непредсказуем любой из источников начального значения.