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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Большинство устройств под управлением последних версий Android включают режим Direct Boot всякий раз, когда установлены учетные данные экрана блокировки (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 или ниже поддерживают «эмулированный» режим 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 если устройство использует файловое шифрование с Direct Boot.

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

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

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