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

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

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

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

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

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

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

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

Приложения должны зарегистрировать свои компоненты в системе, прежде чем они смогут работать в режиме прямой загрузки или получать доступ к зашифрованному хранилищу устройства. Приложения регистрируются в системе, помечая компоненты как поддерживающие шифрование . Чтобы пометить ваш компонент как поддерживающий шифрование, установите для атрибута 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...

Ява

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() с контекстом назначения в качестве вызывающего метода и исходным контекстом в качестве аргумента, чтобы перенести настройки и данные базы данных между хранилищем, зашифрованным учетными данными, и хранилищем, зашифрованным устройством.

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

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

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

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

adb shell getprop ro.crypto.type

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

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

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

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

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

    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 если устройство использует либо полнодисковое шифрование, либо шифрование на основе файлов с прямой загрузкой. В обоих этих случаях данные всегда хранятся в зашифрованном виде.

Если ваше приложение предназначено для 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, описанных на этой странице.