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...
Используйте зашифрованное хранилище устройства только для информации, которая должна быть доступна в режиме прямой загрузки. Не используйте зашифрованное хранилище устройства в качестве универсального зашифрованного хранилища. Для конфиденциальной информации пользователя или зашифрованных данных, которые не нужны в режиме прямой загрузки, используйте зашифрованное хранилище с учётными данными.
Получать уведомления о разблокировке пользователя
Когда пользователь разблокирует устройство после перезапуска, ваше приложение может переключиться на доступ к зашифрованному хранилищу учетных данных и использовать обычные системные службы, которые зависят от учетных данных пользователя.
Чтобы получать уведомления, когда пользователь разблокирует устройство после перезагрузки, зарегистрируйте BroadcastReceiver
в работающем компоненте для прослушивания уведомлений о разблокировке. Когда пользователь разблокирует устройство после загрузки:
- Если в вашем приложении есть активные процессы, требующие немедленного уведомления, прослушивайте сообщение
ACTION_USER_UNLOCKED
. - Если ваше приложение использует только фоновые процессы, которые могут реагировать на отложенные уведомления, прослушивайте сообщение
ACTION_BOOT_COMPLETED
.
Разблокировал ли пользователь устройство, узнать это можно, вызвав UserManager.isUserUnlocked()
.
Перенести существующие данные
Если пользователь обновляет своё устройство для использования режима прямой загрузки, у вас могут быть существующие данные, которые необходимо перенести в зашифрованное хранилище устройства. Используйте Context.moveSharedPreferencesFrom()
и Context.moveDatabaseFrom()
с целевым контекстом в качестве вызывающего метода и исходным контекстом в качестве аргумента для переноса данных настроек и базы данных между зашифрованным хранилищем учётных данных и зашифрованным хранилищем устройства.
Не переносите конфиденциальную информацию пользователей, такую как пароли или токены авторизации, из зашифрованного хранилища с учётными данными в зашифрованное хранилище устройства. При выборе других данных для переноса в зашифрованное хранилище устройства руководствуйтесь здравым смыслом. В некоторых сценариях может потребоваться управление отдельными наборами данных в двух зашифрованных хранилищах.
Протестируйте свое приложение с поддержкой шифрования
Протестируйте приложение с поддержкой шифрования с включенным режимом прямой загрузки.
Большинство устройств под управлением последних версий Android включают режим Direct Boot при установке учётных данных экрана блокировки (PIN-кода, графического ключа или пароля). В частности, это касается всех устройств, использующих файловое шифрование. Чтобы проверить, использует ли устройство файловое шифрование, выполните следующую команду оболочки:
adb shell getprop ro.crypto.type
Если на выходе получается file
, то на устройстве включено файловое шифрование.
На устройствах, на которых по умолчанию не используется файловое шифрование, могут быть другие варианты тестирования режима Direct Boot:
Некоторые устройства, использующие полное шифрование диска (
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
Чтобы отключить эмулированный режим Direct Boot, выполните следующую команду оболочки:
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, описанных на этой странице.