Obsługa trybu bezpośredniego rozruchu

Android 7.0 działa w bezpiecznym trybie Direct Boot, gdy urządzenie jest włączone, ale użytkownik go nie odblokował. W tym celu system udostępnia 2 lokalizacje przechowywania danych:

  • Zaszyfrowany magazyn danych logowania, który jest domyślnym miejscem przechowywania i jest dostępny tylko po odblokowaniu urządzenia przez użytkownika.
  • Zaszyfrowana pamięć urządzenia, czyli lokalizacja pamięci dostępna zarówno w trybie bezpośredniego uruchamiania, jak i po odblokowaniu urządzenia przez użytkownika.

Domyślnie aplikacje nie działają w trybie bezpośredniego uruchamiania. Jeśli aplikacja musi wykonać jakieś działanie w trybie bezpośredniego uruchamiania, możesz zarejestrować komponenty aplikacji, które mają być uruchamiane w tym trybie. Oto kilka typowych zastosowań aplikacji wymagających uruchamiania w trybie bezpośredniego uruchamiania:

  • aplikacje z zaplanowanymi powiadomieniami, takie jak budziki;
  • aplikacje, które wysyłają ważne powiadomienia, np. aplikacje do obsługi SMS-ów;
  • Aplikacje, które zapewniają usługi ułatwień dostępu, takie jak TalkBack.

Jeśli aplikacja potrzebuje dostępu do danych podczas uruchamiania w trybie bezpośredniego uruchamiania, użyj zaszyfrowanego miejsca na dane na urządzeniu. Szyfrowane miejsce na dane na urządzeniu zawiera dane zaszyfrowane kluczem, który jest dostępny dopiero po pomyślnym uruchomieniu urządzenia.

W przypadku danych, które muszą być szyfrowane za pomocą klucza powiązanego z danymi logowania użytkownika, np. z kodem PIN lub hasłem, użyj szyfrowanego magazynu danych logowania. Skryta pamięć z danymi logowania jest dostępna od momentu odblokowania urządzenia przez użytkownika do momentu jego ponownego uruchomienia. Jeśli użytkownik włączy ekran blokady po odblokowaniu urządzenia, magazyn zaszyfrowany danych logowania pozostanie dostępny.

Prośba o dostęp do uruchamiania podczas bezpośredniego uruchamiania

Aplikacje muszą zarejestrować swoje komponenty w systemie, zanim będą mogły działać w trybie bezpośredniego uruchamiania lub uzyskać dostęp do zaszyfrowanej pamięci urządzenia. Aplikacje rejestrują się w systemie, oznaczając komponenty jako świadome szyfrowania. Aby oznaczyć komponent jako obsługujący szyfrowanie, ustaw atrybut android:directBootAware na wartość true w pliku manifestu.

Komponenty obsługujące szyfrowanie mogą zarejestrować się w celu odbierania wiadomości ACTION_LOCKED_BOOT_COMPLETED z systemu po ponownym uruchomieniu urządzenia. W tym momencie pamięć urządzenia szyfrowana jest dostępna, a komponent może wykonywać zadania, które muszą być wykonywane w trybie bezpośredniego uruchamiania, takie jak wyzwalanie zaplanowanego alarmu.

Ten fragment kodu pokazuje, jak zarejestrować BroadcastReceiver jako obsługujący szyfrowanie i dodać w pliku manifestu aplikacji filtr intencji dla ACTION_LOCKED_BOOT_COMPLETED:

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

Gdy użytkownik odblokuje urządzenie, wszystkie komponenty będą miały dostęp zarówno do zaszyfrowanego magazynu danych urządzenia, jak i zaszyfrowanego magazynu danych z danymi logowania.

Dostęp do zaszyfrowanej pamięci urządzenia

Aby uzyskać dostęp do zaszyfrowanego miejsca na dane na urządzeniu, utwórz drugą instancję Context, wywołując Context.createDeviceProtectedStorageContext(). Wszystkie wywołania interfejsu Storage API wykonane przy użyciu tego kontekstu uzyskują dostęp do zaszyfrowanego miejsca na dane urządzenia. W tym przykładzie uzyskujemy dostęp do zaszyfrowanego miejsca na dane na urządzeniu i otwieramy istniejący plik danych aplikacji:

Kotlin

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...

Zaszyfrowanej pamięci urządzenia używaj tylko do przechowywania informacji, które muszą być dostępne w trybie bezpośredniego uruchamiania. Nie używaj zaszyfrowanej pamięci urządzenia jako szyfrowanej pamięci ogólnego przeznaczenia. W przypadku prywatnych informacji użytkownika lub zaszyfrowanych danych, które nie są potrzebne w trybie bezpośredniego uruchamiania, użyj pamięci szyfrowanej za pomocą danych logowania.

Otrzymuj powiadomienia o odblokowaniu przez użytkownika

Gdy użytkownik odblokuje urządzenie po ponownym uruchomieniu, aplikacja może przełączyć się na dostęp do zaszyfrowanego magazynu danych z danymi logowania i wykorzystywać zwykłe usługi systemowe, które zależą od danych logowania użytkownika.

Aby otrzymywać powiadomienia, gdy użytkownik odblokuje urządzenie po ponownym uruchomieniu, zarejestruj BroadcastReceiver z uruchomionego komponentu, aby odbierać powiadomienia o odblokowaniu. Gdy użytkownik odblokuje urządzenie po uruchomieniu:

  • Jeśli aplikacja ma procesy na pierwszym planie, które wymagają natychmiastowego powiadomienia, wysłuchaj wiadomości ACTION_USER_UNLOCKED.
  • Jeśli Twoja aplikacja korzysta tylko z procesów w tle, które mogą działać w odpowiedzi na opóźnione powiadomienie, nasłuchuj wiadomośćACTION_BOOT_COMPLETED.

Jeśli użytkownik odblokował urządzenie, możesz się o tym dowiedzieć, dzwoniąc na numer UserManager.isUserUnlocked().

Migracja dotychczasowych danych

Jeśli użytkownik zaktualizuje urządzenie, aby używać trybu bezpośredniego uruchamiania, możesz mieć istniejące dane, które trzeba przenieść do zaszyfrowanej pamięci urządzenia. Aby przenieść dane preferencji i bazy danych między szyfrowanym magazynem danych z danymi logowania a szyfrowanym magazynem danych na urządzeniu, użyj metod Context.moveSharedPreferencesFrom()Context.moveDatabaseFrom(), gdzie kontekst docelowy jest wywoływaczem metody, a kontekst źródłowy jest argumentem.

Nie przenoś prywatnych informacji o użytkownikach, takich jak hasła czy tokeny autoryzacji, z szyfrowanego magazynu danych na urządzeniu do szyfrowanego magazynu danych na koncie. Decydując, jakie inne dane przenieść do zaszyfrowanej pamięci urządzenia, kieruj się zdrowym rozsądkiem. W niektórych przypadkach może być konieczne zarządzanie osobnymi zestawami danych w 2 zaszyfrowanych magazynach.

Testowanie aplikacji obsługującej szyfrowanie

Przetestuj aplikację obsługującą szyfrowanie z włączonym trybem bezpośredniego uruchamiania.

Większość urządzeń z najnowszymi wersjami Androida włącza tryb bezpośredniego uruchamiania, gdy tylko ustawisz dane uwierzytelniające (kod PIN, wzór lub hasło) na ekranie blokady. Dotyczy to w szczególności wszystkich urządzeń, które używają szyfrowania opartego na plikach. Aby sprawdzić, czy urządzenie używa szyfrowania plików, uruchom to polecenie w powłoce:

adb shell getprop ro.crypto.type

Jeśli dane wyjściowe to file, szyfrowanie oparte na plikach jest włączone.

Na urządzeniach, które domyślnie nie używają szyfrowania opartego na plikach, mogą być dostępne inne opcje testowania trybu bezpośredniego uruchamiania:

  • Niektóre urządzenia, które korzystają z szyfrowania całego dysku (ro.crypto.type=block) i mają zainstalowanego Androida w wersji od 7.0 do 12, można przekształcić w urządzenia z szyfrowaniem na poziomie pliku. Można to zrobić na dwa sposoby:

      Ostrzeżenie: obie metody konwertowania na szyfrowanie plików spowoduje wyczyszczenie wszystkich danych użytkownika na urządzeniu.

    • Jeśli jeszcze tego nie zrobiono, na urządzeniu włącz Opcje programisty. W tym celu otwórz Ustawienia > Informacje o telefonie i kliknij Numer kompilacji siedem razy. Następnie otwórz Ustawienia > Opcje programisty i wybierz Przekształcanie na szyfrowanie plików.
    • Możesz też uruchomić te polecenia w powłoce:
      adb reboot-bootloader
      fastboot --wipe-and-use-fbe
      
  • Urządzenia z Androidem 13 lub niższym obsługują „emulowany” tryb bezpośredniego uruchamiania, który wykorzystuje uprawnienia do plików, aby symulować zablokowanie i odblokowanie zaszyfrowanych plików. Podczas tworzenia używaj tylko trybu emulacji, ponieważ tryb emulacji może spowodować utratę danych. Aby włączyć emulowany tryb bezpośredniego uruchamiania, ustaw wzór blokady na urządzeniu, a gdy pojawi się ekran bezpiecznego uruchamiania, wybierz „Nie, dziękuję”. Następnie uruchom to polecenie w powłoce:

    adb shell sm set-emulate-fbe true
    

    Aby wyłączyć emulowany tryb Direct Boot, uruchom to polecenie w powłoce:

    adb shell sm set-emulate-fbe false
    

    Uruchomienie któregokolwiek z tych poleceń powoduje ponowne uruchomienie urządzenia.

Sprawdzanie stanu szyfrowania zasad dotyczących urządzenia

Aplikacje do zarządzania urządzeniami mogą używać funkcji DevicePolicyManager.getStorageEncryptionStatus() do sprawdzania bieżącego stanu zaszyfrowania urządzenia.

Jeśli Twoja aplikacja jest kierowana na poziom interfejsu API niższy niż Android 7.0 (API 24), funkcja getStorageEncryptionStatus() zwracaENCRYPTION_STATUS_ACTIVE, jeśli urządzenie używa szyfrowania całego dysku lub szyfrowania plików z użyciem funkcji Direct Boot. W obu przypadkach dane są zawsze przechowywane w spoczynku w zaszyfrowanej formie.

Jeśli Twoja aplikacja jest kierowana na Androida 7.0 (interfejs API 24) lub nowszego, funkcja getStorageEncryptionStatus() zwraca wartość ENCRYPTION_STATUS_ACTIVE, jeśli urządzenie używa szyfrowania całego dysku. Zwraca wartość ENCRYPTION_STATUS_ACTIVE_PER_USER, jeśli urządzenie używa szyfrowania plików z Direct Boot.

Jeśli tworzysz aplikację do zarządzania urządzeniami na Androida 7.0, sprawdź, czy jest ona zgodna z wersją ENCRYPTION_STATUS_ACTIVEENCRYPTION_STATUS_ACTIVE_PER_USER, aby określić, czy urządzenie jest zaszyfrowane.

Dodatkowe przykłady kodu

Przykład DirectBoot pokazuje dodatkowe zastosowania interfejsów API opisanych na tej stronie.