Функции

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

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

Keystore предоставляет следующие категории операций:

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

Обратите внимание, что Keystore и KeyMint не обрабатывают операции с открытыми ключами для асимметричных ключей.

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

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

Необходимые примитивы

Все реализации KeyMint обеспечивают:

  • ЮАР
    • Поддержка ключей длиной 2048, 3072 и 4096 бит
    • Поддержка публичной экспоненты F4 (2^16+1)
    • Режимы заполнения для подписи RSA:
      • RSASSA-PSS ( PaddingMode::RSA_PSS )
      • RSASSA-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_SIGN )
    • Режимы дайджеста для подписывания RSA:
      • ША-256
    • Режимы заполнения для шифрования/дешифрования RSA:
      • Без подкладки
      • RSAES-OAEP ( PaddingMode::RSA_OAEP )
      • RSAES-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_ENCRYPT )
  • ECDSA
    • Поддерживаются ключи длиной 224, 256, 384 и 521 бит с использованием кривых NIST P-224, P-256, P-384 и P-521 соответственно.
    • Режимы дайджеста для ECDSA:
      • Нет дайджеста (устарело, будет удалено в будущем)
      • ША-256
  • АЕС
    • Поддерживаются 128- и 256-битные ключи.
    • CBC , CTR, ECB и GCM. Реализация GCM не допускает использования тегов длиной менее 96 бит или одноразовых кодов длиной, отличной от 96 бит.
    • Режимы заполнения PaddingMode::NONE и PaddingMode::PKCS7 поддерживаются для режимов CBC и ECB. Без заполнения шифрование в режимах CBC или ECB завершается ошибкой, если входные данные не кратны размеру блока.
  • HMAC SHA-256 , с любым размером ключа не менее 32 байт.

SHA1 и другие члены семейства SHA2 (SHA-224, SHA384 и SHA512) настоятельно рекомендуются для реализаций KeyMint. Keystore предоставляет их программно, если аппаратная реализация KeyMint их не поддерживает.

Некоторые примитивы также рекомендуются для взаимодействия с другими системами:

  • Меньшие размеры ключей для RSA
  • Произвольные публичные экспоненты для RSA

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

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

Элементы управления доступом определяются как «список авторизации» пар тег/значение. Теги авторизации представляют собой 32-битные целые числа, а значения могут иметь различные типы. Некоторые теги могут повторяться для указания нескольких значений. Возможность повторения тега определяется в интерфейсе KeyMint HAL. При создании ключа вызывающая сторона указывает список авторизации. Реализация KeyMint, лежащая в основе Keystore, изменяет этот список, чтобы указать дополнительную информацию, например, есть ли у ключа защита от отката, и возвращает «окончательный» список авторизации, закодированный в возвращаемом ключевом блоке. Любая попытка использовать ключ для любой криптографической операции завершится неудачей, если окончательный список авторизации будет изменён.

Для Keymaster 2 и более ранних версий набор возможных тегов определён в перечислении keymaster_authorization_tag_t и является постоянно фиксированным (хотя его можно расширить). Именам добавлялся префикс KM_TAG . Четыре верхних бита идентификаторов тегов используются для указания типа.

Keymaster 3 изменил префикс KM_TAG на Tag:: .

Возможные типы включают:

ENUM : Многие значения тегов определены в перечислениях. Например, возможные значения TAG::PURPOSE определены в перечислении keymaster_purpose_t .

ENUM_REP : то же, что и ENUM , за исключением того, что тег может повторяться в списке авторизации. Повторение указывает на наличие нескольких авторизованных значений. Например, ключ шифрования, вероятно, имеет KeyPurpose::ENCRYPT и KeyPurpose::DECRYPT .

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

Аппаратное и программное обеспечение для обеспечения соблюдения правил

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

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

Например, ограничения на дату и время использования ключа обычно не применяются безопасной средой, поскольку у неё нет надёжного доступа к информации о дате и времени. В результате авторизации типа Tag::ORIGINATION_EXPIRE_DATETIME в 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 .

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

Импорт ключа

Keymaster поддерживает только экспорт открытых ключей в формате X.509 и импорт:

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

Чтобы гарантировать, что импортированные ключи можно отличить от ключей, сгенерированных безопасным способом, Tag::ORIGIN включён в соответствующий список авторизации ключей. Например, если ключ был сгенерирован на защищённом оборудовании, Tag::ORIGIN со значением KeyOrigin::GENERATED будет найден в списке hw_enforced характеристик ключа, тогда как ключ, импортированный на защищённое оборудование, будет иметь значение 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 будет скомпрометирован, пока устройство заблокировано.

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

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

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

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

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

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

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

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

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

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

Истечение срока действия

Хранилище ключей поддерживает ограничение использования ключа по дате. Начало действия ключа и истечение срока его действия можно связать с ключом, и Keymaster откажется выполнять операции с ключом, если текущая дата/время выходят за пределы допустимого диапазона. Диапазон действия ключа указывается тегами Tag::ACTIVE_DATETIME , Tag::ORIGINATION_EXPIRE_DATETIME и Tag::USAGE_EXPIRE_DATETIME . Различие между «исходством» и «использованием» основано на том, используется ли ключ для «создания» нового шифротекста/подписи и т. д. или для «использования» существующего шифротекста/подписи и т. д. Обратите внимание, что это различие не отображается в приложениях.

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

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

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

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

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

Отдельные ключи

Некоторые защищённые устройства KeyMint могут хранить ключевой материал внутри себя и возвращать дескрипторы, а не зашифрованный ключевой материал. Возможны и другие случаи, когда ключи невозможно использовать, пока не станет доступен какой-либо другой незащищённый или безопасный компонент системы. Уровень HAL KeyMint позволяет вызывающему объекту запросить «автономность» ключа с помощью тега TAG::STANDALONE , что означает, что не требуются никакие ресурсы, кроме BLOB-объекта и работающей системы KeyMint. Можно проверить теги, связанные с ключом, чтобы определить, является ли ключ автономным. В настоящее время определены только два значения:

  • KeyBlobUsageRequirements::STANDALONE
  • KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM

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

Скорость

При его создании максимальную скорость использования можно указать с помощью TAG::MIN_SECONDS_BETWEEN_OPS . Реализации TrustZone отказываются выполнять криптографические операции с этим ключом, если операция была выполнена менее чем за TAG::MIN_SECONDS_BETWEEN_OPS секунд до этого.

Простой подход к реализации ограничений скорости — это таблица идентификаторов ключей и временных меток последнего использования. Размер этой таблицы ограничен, но она вмещает не менее 16 записей. В случае, если таблица заполнена и ни одна запись не может быть обновлена ​​или удалена, защищенные аппаратные реализации «отказываются», предпочитая отклонять все операции с ключами, ограниченными скоростью, до истечения срока действия одной из записей. Допустимо, чтобы все записи истекали при перезагрузке.

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

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

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

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

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