Поддержка режима прямой загрузки

Android 7.0 работает в безопасном режиме прямой загрузки (Direct Boot), когда устройство включено, но пользователь не разблокировал его. Для этого система предоставляет два места для хранения данных:

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

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

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

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

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

Запросить доступ для выполнения во время прямой загрузки

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

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

Приведённый ниже фрагмент кода — пример того, как зарегистрировать BroadcastReceiver как поддерживающий шифрование и добавить фильтр намерений для ACTION_LOCKED_BOOT_COMPLETED в манифест приложения:

<receiver
  android:directBootAware="true" >
  ...
  <intent-filter>
    <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
  </intent-filter>
</receiver>

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

Доступ к зашифрованному хранилищу устройства

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

Котлин

val directBootContext: Context = appContext.createDeviceProtectedStorageContext()
// Access appDataFilename that lives in device encrypted storage
val inStream: InputStream = directBootContext.openFileInput(appDataFilename)
// Use inStream to read content...

Java

Context directBootContext = appContext.createDeviceProtectedStorageContext();
// Access appDataFilename that lives in device encrypted storage
FileInputStream inStream = directBootContext.openFileInput(appDataFilename);
// Use inStream to read content...

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

Получайте уведомления о разблокировке пользователем

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

Чтобы получать уведомления о разблокировке устройства после перезагрузки, зарегистрируйте BroadcastReceiver в работающем компоненте для прослушивания сообщений об разблокировке. Когда пользователь разблокирует устройство после загрузки:

  • Если в вашем приложении есть процессы на переднем плане, требующие немедленного уведомления, отслеживайте сообщение ACTION_USER_UNLOCKED .
  • Если ваше приложение использует только фоновые процессы, способные реагировать на отложенные уведомления, отслеживайте сообщение ACTION_BOOT_COMPLETED .

Если пользователь разблокировал устройство, это можно узнать, вызвав метод UserManager.isUserUnlocked() .

Перенос существующих данных

Если пользователь обновляет свое устройство для использования режима прямой загрузки, у вас могут остаться данные, которые необходимо перенести в зашифрованное хранилище устройства. Используйте Context.moveSharedPreferencesFrom() и Context.moveDatabaseFrom() , указав в качестве вызывающего метода контекст назначения, а в качестве аргумента — контекст источника, чтобы перенести данные настроек и базы данных между зашифрованным хранилищем учетных данных и зашифрованным хранилищем устройства.

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

Протестируйте ваше приложение, поддерживающее шифрование.

Протестируйте ваше приложение, поддерживающее шифрование, в режиме прямой загрузки (Direct Boot).

Большинство устройств, работающих под управлением последних версий Android, включают режим Direct Boot всякий раз, когда установлены учетные данные для блокировки экрана (PIN-код, графический ключ или пароль). В частности, это относится ко всем устройствам, использующим шифрование на основе файлов. Чтобы проверить, использует ли устройство шифрование на основе файлов, выполните следующую команду в командной оболочке:

adb shell getprop ro.crypto.type

Если на выходе получается file , значит, на устройстве включено шифрование на основе файлов.

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

  • Некоторые устройства, использующие полнодисковое шифрование ( ro.crypto.type=block ) и работающие под управлением Android 7.0–12, могут быть переведены на файловое шифрование. Для этого есть два способа:

      Внимание: любой из способов перехода к файловому шифрованию приводит к удалению всех пользовательских данных на устройстве.

    • Если у вас еще нет включенных параметров разработчика , перейдите в «Настройки» > «О телефоне» и семь раз нажмите на «Номер сборки» . Затем перейдите в «Настройки» > «Параметры разработчика» и выберите «Преобразовать в шифрование файлов» .
    • В качестве альтернативы выполните следующие команды оболочки:
      adb reboot-bootloader
      fastboot --wipe-and-use-fbe
      
  • Устройства под управлением Android 13 или более ранних версий поддерживают «эмулированный» режим Direct Boot, который использует права доступа к файлам для имитации блокировки и разблокировки зашифрованных файлов. Используйте эмулированный режим только во время разработки; он может привести к потере данных. Чтобы включить эмулированный режим Direct Boot, установите графический ключ на устройстве, выберите «Нет, спасибо», если при установке графического ключа появится запрос на безопасный экран запуска, а затем выполните следующую команду в командной оболочке:

    adb shell sm set-emulate-fbe true
    

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

    adb shell sm set-emulate-fbe false
    

    Выполнение любой из этих команд приводит к перезагрузке устройства.

Проверьте состояние шифрования политики устройства.

Приложения для администрирования устройств могут использовать DevicePolicyManager.getStorageEncryptionStatus() для проверки текущего состояния шифрования устройства.

Если ваше приложение ориентировано на API-уровень ниже Android 7.0 (API 24), getStorageEncryptionStatus() возвращает ENCRYPTION_STATUS_ACTIVE если устройство использует либо полное шифрование диска, либо шифрование на основе файлов с помощью Direct Boot. В обоих этих случаях данные всегда хранятся в зашифрованном виде в состоянии покоя.

Если ваше приложение ориентировано на Android 7.0 (API 24) или выше, getStorageEncryptionStatus() возвращает ENCRYPTION_STATUS_ACTIVE если устройство использует полное шифрование диска. Она возвращает ENCRYPTION_STATUS_ACTIVE_PER_USER если устройство использует шифрование на основе файлов с прямой загрузкой.

Если вы разрабатываете приложение для администрирования устройств, ориентированное на Android 7.0, обязательно проверяйте значения ENCRYPTION_STATUS_ACTIVE и ENCRYPTION_STATUS_ACTIVE_PER_USER , чтобы определить, зашифровано ли устройство.

Дополнительные примеры кода

Пример использования DirectBoot дополнительно демонстрирует применение API, описанных на этой странице.