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-bootloaderfastboot --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, описанных на этой странице.