Android 7.0 i nowsze wersje obsługują szyfrowanie oparte na plikach (FBE). Szyfrowanie oparte na plikach umożliwia szyfrowanie różnych plików za pomocą różnych kluczy, które można odblokować niezależnie od siebie.
Z tego artykułu dowiesz się, jak włączyć szyfrowanie oparte na plikach na nowych urządzeniach i jak aplikacje systemowe mogą korzystać z interfejsów Direct Boot API, aby zapewnić użytkownikom jak najlepsze i najbezpieczniejsze wrażenia.
Wszystkie urządzenia z Androidem 10 lub nowszym muszą korzystać z szyfrowania opartego na plikach.
Bezpośredni rozruch
Szyfrowanie oparte na plikach umożliwia korzystanie z nowej funkcji wprowadzonej w Androidzie 7.0 o nazwie bezpośrednie uruchamianie. Bezpośrednie uruchamianie umożliwia uruchamianie zaszyfrowanych urządzeń bezpośrednio na ekranie blokady. Wcześniej na zaszyfrowanych urządzeniach korzystających z szyfrowania całego dysku (FDE) użytkownicy musieli podać dane logowania, zanim można było uzyskać dostęp do jakichkolwiek danych, co uniemożliwiało telefonowi wykonywanie wszystkich operacji z wyjątkiem najbardziej podstawowych. Na przykład alarmy nie działały, usługi ułatwień dostępu były niedostępne, a telefony nie mogły odbierać połączeń, tylko wykonywać podstawowe połączenia alarmowe.
Wprowadzenie szyfrowania opartego na plikach (FBE) i nowych interfejsów API, które informują aplikacje o szyfrowaniu, umożliwia im działanie w ograniczonym kontekście. Może się to zdarzyć, zanim użytkownicy podadzą swoje dane logowania, przy jednoczesnej ochronie prywatnych informacji o użytkownikach.
Na urządzeniu z szyfrowaniem opartym na plikach każdy użytkownik ma 2 lokalizacje pamięci dostępne dla aplikacji:
- pamięć Credential Encrypted (CE), która jest domyślną lokalizacją przechowywania i jest dostępna tylko po odblokowaniu urządzenia przez użytkownika;
- pamięć zaszyfrowana na urządzeniu (DE), która jest dostępna zarówno w trybie bezpośredniego uruchamiania, jak i po odblokowaniu urządzenia przez użytkownika;
Dzięki temu profile służbowe są bezpieczniejsze, ponieważ umożliwiają ochronę więcej niż jednego użytkownika naraz, a szyfrowanie nie jest już oparte wyłącznie na haśle używanym podczas uruchamiania.
Interfejs Direct Boot API umożliwia aplikacjom obsługującym szyfrowanie dostęp do każdego z tych obszarów. W cyklu życia aplikacji wprowadzono zmiany, aby uwzględnić potrzebę powiadamiania aplikacji, gdy pamięć CE użytkownika jest odblokowywana w odpowiedzi na pierwsze wprowadzenie danych logowania na ekranie blokady lub w przypadku profilu służbowego, gdy użytkownik przejdzie weryfikację służbową. Urządzenia z Androidem 7.0 muszą obsługiwać te nowe interfejsy API i cykle życia niezależnie od tego, czy implementują FBE. Bez FBE pamięć DE i CE jest zawsze odblokowana.
Pełna implementacja szyfrowania opartego na plikach w systemach plików Ext4 i F2FS jest dostępna w ramach Projektu Android Open Source (AOSP) i wymaga tylko włączenia na urządzeniach spełniających wymagania. Producenci, którzy zdecydują się na korzystanie z FBE, mogą szukać sposobów na optymalizację tej funkcji w zależności od używanego układu SOC.
Wszystkie niezbędne pakiety w AOSP zostały zaktualizowane, aby obsługiwać bezpośrednie uruchamianie. Jeśli jednak producenci urządzeń używają dostosowanych wersji tych aplikacji, chcą mieć pewność, że pakiety obsługujące bezpośrednie uruchamianie zapewniają co najmniej te usługi:
- Usługi telefoniczne i dialer
- Metoda wpisywania haseł na ekranie blokady
Przykłady i źródło
Android udostępnia referencyjną implementację szyfrowania opartego na plikach, w której vold (system/vold) zapewnia funkcje zarządzania urządzeniami pamięci masowej i woluminami na Androidzie. Dodanie FBE zapewnia usłudze vold kilka nowych poleceń, które obsługują zarządzanie kluczami CE i DE wielu użytkowników. Oprócz podstawowych zmian związanych z korzystaniem z możliwości szyfrowania w jądrze opartych na plikach zmodyfikowano wiele pakietów systemowych, w tym ekran blokady i interfejs systemowy, aby obsługiwały funkcje szyfrowania opartego na plikach i bezpośredniego rozruchu. Należą do nich:
- Aplikacja Telefon (packages/apps/Dialer)
- Zegar biurkowy (packages/apps/DeskClock)
- LatinIME (packages/inputmethods/LatinIME)*
- Aplikacja Ustawienia (packages/apps/Settings)*
- SystemUI (frameworks/base/packages/SystemUI)*
* Aplikacje systemowe, które używają defaultToDeviceProtectedStorage
atrybutu manifestu
Więcej przykładów aplikacji i usług, które obsługują szyfrowanie, znajdziesz, uruchamiając polecenie mangrep directBootAware
w katalogu frameworks lub packages w drzewie źródłowym AOSP.
Zależności
Aby bezpiecznie korzystać z implementacji FBE w AOSP, urządzenie musi spełniać te wymagania:
- Obsługa jądra w przypadku szyfrowania Ext4 lub F2FS.
- KeyMint (lub Keymaster w wersji 1.0 lub nowszej) Obsługa Nie obsługujemy Keymastera 0.3, ponieważ nie zapewnia on niezbędnych funkcji ani wystarczającej ochrony kluczy szyfrowania.
- KeyMint/Keymaster i Gatekeeper muszą być wdrożone w zaufanym środowisku wykonawczym (TEE), aby chronić klucze DE. Dzięki temu nieautoryzowany system operacyjny (niestandardowy system operacyjny wgrany na urządzenie) nie może po prostu zażądać kluczy DE.
- Sprzętowy korzeń zaufania i weryfikacja podczas uruchamiania powiązane z inicjalizacją KeyMint są wymagane, aby klucze DE nie były dostępne dla nieautoryzowanego systemu operacyjnego.
Implementacja
Przede wszystkim aplikacje takie jak budziki, telefony i funkcje ułatwień dostępu powinny być zgodne z atrybutem android:directBootAware zgodnie z dokumentacją dla programistów dotyczącą bezpośredniego uruchamiania.
Obsługa jądra
Obsługa szyfrowania Ext4 i F2FS w jądrze jest dostępna w wersji 3.18 i nowszych wspólnych jąder Androida. Aby włączyć tę funkcję w jądrze w wersji 5.1 lub nowszej, użyj tego polecenia:
CONFIG_FS_ENCRYPTION=y
W przypadku starszych jąder użyj CONFIG_EXT4_ENCRYPTION=y
, jeśli system plików urządzenia to Ext4, lub CONFIG_F2FS_FS_ENCRYPTION=y
, jeśli system plików urządzenia to F2FS.userdata
userdata
Jeśli urządzenie obsługuje pamięć adaptacyjną lub korzysta z szyfrowania metadanych w pamięci wewnętrznej, włącz też opcje konfiguracji jądra wymagane do szyfrowania metadanych zgodnie z opisem w dokumentacji szyfrowania metadanych.
Oprócz obsługi szyfrowania Ext4 lub F2FS producenci urządzeń powinni też włączyć akcelerację kryptograficzną, aby przyspieszyć szyfrowanie oparte na plikach i poprawić komfort użytkowania. Na przykład na urządzeniach z architekturą ARM64 akcelerację ARMv8 CE (Cryptography Extensions) można włączyć, ustawiając te opcje konfiguracji jądra:
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_SHA2_ARM64_CE=y
Aby jeszcze bardziej zwiększyć wydajność i zmniejszyć zużycie energii, producenci urządzeń mogą też wdrożyć sprzęt do szyfrowania wbudowanego, który szyfruje i odszyfrowuje dane podczas przesyłania do i z urządzenia pamięci masowej. Wspólne jądra Androida (wersja 4.14 i nowsze) zawierają platformę, która umożliwia korzystanie z szyfrowania wbudowanego, gdy dostępne jest wsparcie sprzętowe i sterowniki dostawcy. Ramkę szyfrowania wbudowanego można włączyć, ustawiając te opcje konfiguracji jądra:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
Jeśli urządzenie korzysta z pamięci UFS, włącz też:
CONFIG_SCSI_UFS_CRYPTO=y
Jeśli urządzenie korzysta z pamięci eMMC, włącz też:
CONFIG_MMC_CRYPTO=y
Włączanie szyfrowania opartego na plikach
Włączenie szyfrowania FBE na urządzeniu wymaga włączenia go na pamięci wewnętrznej (userdata
). Spowoduje to również automatyczne włączenie szyfrowania FBE na pamięci przenośnej. W razie potrzeby format szyfrowania na pamięci przenośnej można jednak zastąpić.
Pamięć wewnętrzna
FBE jest włączane przez dodanie opcji
fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]]
do kolumny fs_mgr_flags w wierszu fstab
dla
userdata
. Ta opcja określa format szyfrowania na wewnętrznej pamięci
masowej. Zawiera maksymalnie 3 parametry oddzielone dwukropkami:
- Parametr
contents_encryption_mode
określa, który algorytm kryptograficzny jest używany do szyfrowania zawartości pliku. Może to byćaes-256-xts
lubadiantum
. Od Androida 11 można też pozostawić to pole puste, aby określić algorytm domyślny, czyliaes-256-xts
. - Parametr
filenames_encryption_mode
określa algorytm kryptograficzny używany do szyfrowania nazw plików. Może to byćaes-256-cts
,aes-256-heh
,adiantum
lubaes-256-hctr2
. Jeśli nie podasz tu żadnej wartości, zostanie użyta wartość domyślnaaes-256-cts
, jeślicontents_encryption_mode
toaes-256-xts
, lubadiantum
, jeślicontents_encryption_mode
toadiantum
. - Parametr
flags
, który jest nowością w Androidzie 11, to lista flag rozdzielonych znakiem+
. Obsługiwane są te flagi:- Flaga
v1
wybiera zasady szyfrowania w wersji 1, a flagav2
wybiera zasady szyfrowania w wersji 2. Wersja 2 zasady szyfrowania korzystają z bezpieczniejszej i bardziej elastycznej funkcji derywacji klucza. Domyślnie jest to v2, jeśli urządzenie zostało wprowadzone na rynek z Androidem 11 lub nowszym (określa toro.product.first_api_level
), lub v1, jeśli urządzenie zostało wprowadzone na rynek z Androidem 10 lub starszym. - Flaga
inlinecrypt_optimized
wybiera format szyfrowania zoptymalizowany pod kątem sprzętu do szyfrowania wbudowanego, który nie obsługuje wydajnie dużej liczby kluczy. W tym celu generuje tylko jeden klucz szyfrowania zawartości pliku na klucz CE lub DE, a nie jeden na plik. Generowanie wektorów inicjujących jest odpowiednio dostosowywane. - Flaga
emmc_optimized
jest podobna doinlinecrypt_optimized
, ale wybiera też metodę generowania wektora inicjującego, która ogranicza wektory inicjujące do 32 bitów. Tej flagi należy używać tylko w przypadku sprzętu do szyfrowania wbudowanego, który jest zgodny ze specyfikacją JEDEC eMMC w wersji 5.2 i dlatego obsługuje tylko 32-bitowe wektory inicjujące. W przypadku innego sprzętu do szyfrowania wbudowanego użyjinlinecrypt_optimized
. Tego flagi nie należy nigdy używać w przypadku pamięci opartej na UFS. Specyfikacja UFS dopuszcza używanie 64-bitowych wektorów inicjujących. - Na urządzeniach, które obsługują klucze opakowane sprzętowo, flaga
wrappedkey_v0
umożliwia używanie kluczy opakowanych sprzętowo na potrzeby szyfrowania opartego na plikach. Można jej używać tylko w połączeniu z opcją montowaniainlinecrypt
i flagąinlinecrypt_optimized
lubemmc_optimized
. - Flaga
dusize_4k
wymusza rozmiar jednostki danych szyfrowania na 4096 bajtów, nawet jeśli rozmiar bloku systemu plików nie wynosi 4096 bajtów. Rozmiar jednostki danych szyfrowania to ziarnistość szyfrowania zawartości pliku. Ta flaga jest dostępna od Androida 15. Tej flagi należy używać tylko do włączania sprzętu do szyfrowania wbudowanego, który nie obsługuje jednostek danych większych niż 4096 bajtów, na urządzeniu, które używa rozmiaru strony większego niż 4096 bajtów i systemu plików f2fs.
- Flaga
Jeśli nie używasz sprzętu do szyfrowania wbudowanego, zalecane ustawienie dla większości urządzeń to fileencryption=aes-256-xts
. Jeśli używasz sprzętu do szyfrowania wbudowanego, zalecane ustawienie dla większości urządzeń to fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized
(lub równoważne fileencryption=::inlinecrypt_optimized
). Na urządzeniach bez żadnej formy akceleracji AES zamiast AES można użyć Adiantum, ustawiając fileencryption=adiantum
.
Od Androida 14 preferowanym trybem szyfrowania nazw plików jest AES-HCTR2 na urządzeniach z instrukcjami przyspieszonego szyfrowania. Jednak tylko nowsze jądra Androida obsługują AES-HCTR2. W przyszłej wersji Androida ma się stać domyślnym trybem szyfrowania nazw plików. Jeśli jądro obsługuje AES-HCTR2, można włączyć szyfrowanie nazw plików, ustawiając filenames_encryption_mode
na aes-256-hctr2
. W najprostszym przypadku można to zrobić za pomocą znaku fileencryption=aes-256-xts:aes-256-hctr2
.
Na urządzeniach, które zostały wprowadzone na rynek z Androidem 10 lub starszym, akceptowany jest też znak fileencryption=ice
, który określa użycie trybu szyfrowania zawartości pliku FSCRYPT_MODE_PRIVATE
. Ten tryb nie jest zaimplementowany w wersjach jądra Androida, ale może być zaimplementowany przez dostawców za pomocą niestandardowych poprawek jądra. Format na dysku wygenerowany w tym trybie był specyficzny dla dostawcy. Na urządzeniach z Androidem 11 lub nowszym ten tryb nie jest już dozwolony i zamiast niego należy używać standardowego formatu szyfrowania.
Domyślnie szyfrowanie zawartości plików odbywa się za pomocą interfejsu API kryptografii jądra systemu Linux. Jeśli zamiast tego chcesz używać sprzętu do szyfrowania wbudowanego, dodaj też opcję montowania inlinecrypt
. Na przykład pełna linia może wyglądać tak:fstab
/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized
Pamięć dostosowywana
Od Androida 9 można używać FBE i pamięci przenośnej jednocześnie.
Określenie opcji fileencryption
fstab dla userdata
automatycznie włącza zarówno szyfrowanie oparte na plikach, jak i szyfrowanie metadanych na pamięci przenośnej. Możesz jednak zastąpić formaty szyfrowania FBE lub metadanych na pamięci przenośnej, ustawiając właściwości w PRODUCT_PROPERTY_OVERRIDES
.
Na urządzeniach, które zostały wprowadzone na rynek z Androidem 11 lub nowszym, używaj tych właściwości:
ro.crypto.volume.options
(nowość w Androidzie 11) wybiera format szyfrowania FBE na pamięci wewnętrznej. Ma taką samą składnię jak argument opcjifileencryption
fstab i używa tych samych wartości domyślnych. W sekcjifileencryption
powyżej znajdziesz rekomendacje dotyczące tego, co należy tu wpisać.ro.crypto.volume.metadata.encryption
wybiera format szyfrowania metadanych na pamięci wewnętrznej. Zapoznaj się z dokumentacją dotyczącą szyfrowania metadanych.
Na urządzeniach, które zostały wprowadzone na rynek z Androidem 10 lub starszym, używaj tych właściwości:
ro.crypto.volume.contents_mode
wybiera tryb szyfrowania treści. Jest to odpowiednik pierwszego pola rozdzielonego dwukropkiem wro.crypto.volume.options
.ro.crypto.volume.filenames_mode
wybiera tryb szyfrowania nazw plików. Jest to odpowiednik drugiego pola rozdzielonego dwukropkiem wro.crypto.volume.options
, z tym wyjątkiem, że domyślna wartość na urządzeniach z Androidem 10 i starszymi wersjami toaes-256-heh
. Na większości urządzeń trzeba to wyraźnie zmienić naaes-256-cts
.ro.crypto.fde_algorithm
iro.crypto.fde_sector_size
wybierz format szyfrowania metadanych na pamięci wewnętrznej. Zapoznaj się z dokumentacją dotyczącą szyfrowania metadanych.
Integracja z KeyMint
HAL KeyMint powinien być uruchamiany w ramach klasy early_hal
.
Dzieje się tak, ponieważ FBE wymaga, aby KeyMint był gotowy do obsługi żądań w post-fs-data
fazie rozruchu, czyli wtedy, gdy vold
konfiguruje
początkowe klucze.
Wykluczanie katalogów
init
stosuje systemowy klucz DE do wszystkich katalogów najwyższego poziomu na dysku /data
, z wyjątkiem katalogów, które muszą być nieszyfrowane, takich jak katalog zawierający sam systemowy klucz DE oraz katalogi zawierające katalogi CE lub DE użytkownika. Klucze szyfrowania są stosowane rekursywnie i nie można ich zastąpić w podkatalogach.
W Androidzie 11 i nowszych klucz, któryinit
ma zastosowanie do katalogów, można kontrolować za pomocą argumentuencryption=<action>
polecenia mkdir
w skryptach inicjujących. Możliwe wartości <action>
są opisane w pliku README języka inicjowania Androida.
W Androidzie 10 init
działania związane z szyfrowaniem
były na stałe zakodowane w tym miejscu:
/system/extras/libfscrypt/fscrypt_init_extensions.cpp
Na Androidzie 9 i starszych lokalizacja była następująca:
/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp
Możesz dodać wyjątki, aby zapobiec szyfrowaniu niektórych katalogów. Jeśli takie modyfikacje zostaną wprowadzone, producent urządzenia powinien uwzględnić zasady SELinux, które przyznają dostęp tylko aplikacjom, które muszą korzystać z niezaszyfrowanego katalogu. Powinno to wykluczyć wszystkie niezaufane aplikacje.
Jedynym znanym dopuszczalnym przypadkiem użycia jest obsługa starszych funkcji OTA.
Obsługa bezpośredniego rozruchu w aplikacjach systemowych
Dostosowywanie aplikacji do bezpośredniego rozruchu
Aby ułatwić szybką migrację aplikacji systemowych, wprowadziliśmy 2 nowe atrybuty, które można ustawić na poziomie aplikacji. Atrybut
defaultToDeviceProtectedStorage
jest dostępny tylko w przypadku aplikacji systemowych. Atrybut directBootAware
jest dostępny dla wszystkich.
<application android:directBootAware="true" android:defaultToDeviceProtectedStorage="true">
Atrybut directBootAware
na poziomie aplikacji jest skrótem oznaczającym, że wszystkie komponenty w aplikacji są przystosowane do szyfrowania.
Atrybut defaultToDeviceProtectedStorage
przekierowuje domyślną lokalizację zapisu aplikacji na pamięć DE zamiast na pamięć CE.
Aplikacje systemowe korzystające z tego flagi muszą dokładnie sprawdzić wszystkie dane przechowywane w domyślnej lokalizacji i zmienić ścieżki danych wrażliwych, aby korzystać z pamięci CE. Producenci urządzeń korzystający z tej opcji powinni dokładnie sprawdzać przechowywane dane, aby upewnić się, że nie zawierają one danych osobowych.
W tym trybie dostępne są te interfejsy API systemu, które umożliwiają w razie potrzeby bezpośrednie zarządzanie kontekstem obsługiwanym przez pamięć CE. Są one odpowiednikami interfejsów API chronionych na urządzeniu.
Context.createCredentialProtectedStorageContext()
Context.isCredentialProtectedStorage()
Obsługa wielu użytkowników
Każdy użytkownik w środowisku wielodostępnym otrzymuje osobny klucz szyfrowania. Każdy użytkownik otrzymuje 2 klucze: DE i CE. Użytkownik 0 musi najpierw zalogować się na urządzeniu, ponieważ jest to użytkownik specjalny. Jest to istotne w przypadku korzystania z administrowania urządzeniami.
Aplikacje obsługujące kryptowaluty wchodzą w interakcje z użytkownikami w ten sposób:INTERACT_ACROSS_USERS
i INTERACT_ACROSS_USERS_FULL
umożliwiają aplikacji działanie na wszystkich kontach użytkowników na urządzeniu. Te aplikacje mogą jednak uzyskiwać dostęp tylko do katalogów zaszyfrowanych za pomocą CE w przypadku użytkowników, którzy są już odblokowani.
Aplikacja może swobodnie wchodzić w interakcje w obszarach DE, ale odblokowanie jednego użytkownika nie oznacza, że wszyscy użytkownicy na urządzeniu są odblokowani. Aplikacja powinna sprawdzić ten stan przed próbą uzyskania dostępu do tych obszarów.
Każdy identyfikator użytkownika profilu służbowego otrzymuje też 2 klucze: DE i CE. Gdy wyzwanie służbowe zostanie spełnione, profil użytkownika zostanie odblokowany, a KeyMint (w TEE) może udostępnić klucz TEE profilu.
Obsługa aktualizacji
Partycja odzyskiwania nie ma dostępu do pamięci chronionej przez DE na partycji userdata. Urządzenia z szyfrowaniem opartym na plikach powinny obsługiwać aktualizacje OTA za pomocą aktualizacji systemu A/B. Aktualizację OTA można zastosować podczas normalnego działania, więc nie trzeba przywracać dostępu do danych na zaszyfrowanym dysku.
Jeśli używasz starszego rozwiązania OTA, które wymaga przywrócenia, aby uzyskać dostęp do pliku OTA na partycji userdata
:
- Utwórz katalog najwyższego poziomu (np.
misc_ne
) w partycjiuserdata
. - Skonfiguruj ten katalog najwyższego poziomu jako niezaszyfrowany (patrz Wykluczanie katalogów).
- Utwórz w katalogu najwyższego poziomu katalog do przechowywania pakietów OTA.
- Dodaj regułę SELinux i konteksty plików, aby kontrolować dostęp do tego katalogu i jego zawartości. Tylko proces lub aplikacje otrzymujące aktualizacje OTA powinny mieć możliwość odczytu i zapisu w tym katalogu. Żadna inna aplikacja ani proces nie powinny mieć dostępu do tego katalogu.
Weryfikacja
Aby upewnić się, że wdrożona wersja funkcji działa zgodnie z oczekiwaniami, najpierw przeprowadź wiele testów szyfrowania CTS, takich jak DirectBootHostTest i EncryptionTest.
Jeśli urządzenie ma Androida 11 lub nowszego, uruchom też vts_kernel_encryption_test:
atest vts_kernel_encryption_test
lub:
vts-tradefed run vts -m vts_kernel_encryption_test
Dodatkowo producenci urządzeń mogą przeprowadzać te testy ręczne. Na urządzeniu z włączonym szyfrowaniem na poziomie plików:
- Sprawdź, czy
ro.crypto.state
istnieje.- Sprawdź, czy
ro.crypto.state
jest zaszyfrowany
- Sprawdź, czy
- Sprawdź, czy
ro.crypto.type
istnieje.- Sprawdź, czy nagłówek
ro.crypto.type
jest ustawiony nafile
.
- Sprawdź, czy nagłówek
Dodatkowo testerzy mogą sprawdzić, czy pamięć CE jest zablokowana, zanim urządzenie zostanie odblokowane po raz pierwszy od momentu uruchomienia. Aby to zrobić, użyj kompilacji userdebug
lub eng
, ustaw kod PIN, wzór lub hasło dla głównego użytkownika i ponownie uruchom urządzenie. Przed odblokowaniem urządzenia uruchom to polecenie, aby sprawdzić pamięć CE głównego użytkownika. Jeśli urządzenie korzysta z trybu użytkownika systemu bez monitora (większość urządzeń samochodowych), głównym użytkownikiem jest użytkownik 10, więc uruchom:
adb root; adb shell ls /data/user/10
Na innych urządzeniach (większości urządzeń innych niż Automotive) głównym użytkownikiem jest użytkownik 0, więc wykonaj to polecenie:
adb root; adb shell ls /data/user/0
Sprawdź, czy wymienione nazwy plików są zakodowane w formacie Base64. Oznacza to, że nazwy plików są zaszyfrowane, a klucz do ich odszyfrowania nie jest jeszcze dostępny. Jeśli nazwy plików są wymienione w formie zwykłego tekstu, coś jest nie tak.
Zachęcamy też producentów urządzeń do przeprowadzania na nich lub na ich jądrach testów fscrypt w wersji upstream dla Linuksa. Te testy są częścią pakietu testów systemu plików xfstests. Te testy nie są jednak oficjalnie obsługiwane przez Androida.
Szczegóły implementacji AOSP
Ta sekcja zawiera szczegółowe informacje o implementacji AOSP i opisuje, jak działa szyfrowanie oparte na plikach. Producenci urządzeń nie powinni wprowadzać tu żadnych zmian, aby korzystać na swoich urządzeniach z szyfrowania opartego na plikach i bezpośredniego rozruchu.
szyfrowanie fscrypt,
Implementacja AOSP korzysta z szyfrowania „fscrypt” (obsługiwanego przez systemy plików ext4 i f2fs) w jądrze i jest zwykle skonfigurowana w ten sposób:
- Szyfrowanie zawartości pliku za pomocą AES-256 w trybie XTS
- Szyfrowanie nazw plików za pomocą AES-256 w trybie CBC-CTS
Obsługiwane jest też szyfrowanie Adiantum. Gdy szyfrowanie Adiantum jest włączone, zarówno zawartość plików, jak i ich nazwy są szyfrowane za pomocą tego algorytmu.
fscrypt obsługuje 2 wersje zasad szyfrowania: wersję 1 i wersję 2. Wersja 1 jest wycofana, a wymagania CDD dotyczące urządzeń z Androidem 11 lub nowszym są zgodne tylko z wersją 2. Zasady szyfrowania w wersji 2 używają funkcji HKDF-SHA512 do wyprowadzania rzeczywistych kluczy szyfrowania z kluczy dostarczonych przez przestrzeń użytkownika.
Więcej informacji o fscrypt znajdziesz w dokumentacji jądra.
Klasy pamięci
W tabeli poniżej znajdziesz szczegółowe informacje o kluczach FBE i katalogach, które chronią:
Klasa pamięci | Opis | Katalogi |
---|---|---|
Niezaszyfrowane | Katalogi w /data , które nie mogą być lub nie muszą być chronione przez FBE. Na urządzeniach, które korzystają z szyfrowania metadanych, te katalogi nie są w rzeczywistości nieszyfrowane, ale są chronione przez klucz szyfrowania metadanych, który jest odpowiednikiem klucza DE systemu. |
|
System DE | Dane zaszyfrowane na urządzeniu, które nie są powiązane z konkretnym użytkownikiem |
|
Po uruchomieniu | tymczasowe pliki systemowe, które nie muszą przetrwać ponownego uruchomienia; | /data/per_boot |
Użytkownik CE (wewnętrzny) | Dane zaszyfrowane za pomocą danych logowania poszczególnych użytkowników w pamięci wewnętrznej |
|
Użytkownik DE (wewnętrzny) | Dane zaszyfrowane na urządzeniu i przechowywane w pamięci wewnętrznej dla każdego użytkownika |
|
Urządzenie użytkownika (możliwe do przeniesienia) | Dane zaszyfrowane za pomocą danych logowania poszczególnych użytkowników w pamięci dostosowywanej |
|
Użytkownik DE (możliwość przeniesienia) | Dane zaszyfrowane na urządzeniu dla każdego użytkownika na pamięci przenośnej |
|
Przechowywanie i ochrona kluczy
Wszystkie klucze FBE są zarządzane przez vold
i przechowywane na dysku w postaci zaszyfrowanej, z wyjątkiem klucza używanego podczas uruchamiania, który nie jest w ogóle przechowywany. W tabeli poniżej znajdziesz lokalizacje, w których są przechowywane różne klucze FBE:
Typ klucza | Lokalizacja klucza | Klasa pamięci lokalizacji klucza |
---|---|---|
Klucz DE systemu | /data/unencrypted |
Niezaszyfrowane |
Klucze CE użytkownika (wewnętrzne) | /data/misc/vold/user_keys/ce/${user_id} |
System DE |
Klucze użytkownika DE (wewnętrzne) | /data/misc/vold/user_keys/de/${user_id} |
System DE |
Klucze użytkownika CE (możliwe do przeniesienia) | /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} |
Użytkownik CE (wewnętrzny) |
Klucze DE użytkownika (możliwe do przeniesienia) | /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} |
Użytkownik DE (wewnętrzny) |
Jak widać w tabeli powyżej, większość kluczy FBE jest przechowywana w katalogach zaszyfrowanych innym kluczem FBE. Kluczy nie można odblokować, dopóki nie zostanie odblokowana klasa pamięci, w której się znajdują.
vold
stosuje też warstwę szyfrowania do wszystkich kluczy FBE. Każdy klucz oprócz kluczy CE do pamięci wewnętrznej jest szyfrowany algorytmem AES-256-GCM przy użyciu własnego klucza Keystore, który nie jest udostępniany poza TEE. Dzięki temu klucze FBE nie mogą zostać odblokowane, dopóki nie zostanie uruchomiony zaufany system operacyjny, co jest wymuszane przez weryfikację podczas uruchamiania. W przypadku klucza Keystore wymagana jest też odporność na przywracanie, która umożliwia bezpieczne usuwanie kluczy FBE na urządzeniach, na których KeyMint obsługuje odporność na przywracanie. W przypadku braku odporności na wycofanie jako najlepsze rozwiązanie awaryjne stosowany jest skrót SHA-512 16384 losowych bajtów przechowywanych w pliku secdiscardable
zapisanym obok klucza. Jest on używany jako Tag::APPLICATION_ID
klucza Keystore. Aby odzyskać klucz FBE, musisz odzyskać wszystkie te bajty.
Klucze CE do pamięci wewnętrznej są lepiej chronione, co zapewnia, że nie można ich odblokować bez znajomości czynnika wiedzy dotyczącego blokady ekranu (LSKF) (kodu PIN, wzoru lub hasła), bezpiecznego tokena resetowania hasła lub kluczy po stronie klienta i serwera w przypadku operacji wznawiania po ponownym uruchomieniu. Tokeny resetowania kodu dostępu można tworzyć tylko w przypadku profili służbowych i w pełni zarządzanych urządzeń.
W tym celu vold
szyfruje każdy klucz CE na potrzeby wewnętrznego przechowywania
przy użyciu klucza AES-256-GCM pochodzącego z syntetycznego hasła użytkownika.
Hasło syntetyczne to niezmienny, kryptograficzny klucz tajny o wysokiej entropii, który jest generowany losowo dla każdego użytkownika. LockSettingsService
w system_server
zarządza hasłem syntetycznym i sposobami jego ochrony.
Aby chronić hasło syntetyczne za pomocą LSKF, najpierw rozciąga LSKF, przekazując go przez scrypt
, co zajmuje około 25 ms i wykorzystuje około 2 MiB pamięci.LockSettingsService
LSKF są zwykle krótkie, więc ten krok nie zapewnia dużego bezpieczeństwa. Główną warstwą zabezpieczeń jest Secure Element (SE) lub ograniczenie liczby żądań wymuszane przez TEE, opisane poniżej.
Jeśli urządzenie ma element Secure Element (SE), LockSettingsService
mapuje rozciągnięty klucz LSKF na losowy sekret o wysokiej entropii przechowywany w elemencie SE za pomocą Weaver HAL. LockSettingsService
następnie szyfruje hasło syntetyczne 2 razy: najpierw za pomocą klucza programowego pochodzącego z rozszerzonego klucza LSKF i tajnego klucza Weaver, a potem za pomocą klucza Keystore niezwiązanego z uwierzytelnianiem. Zapewnia to ograniczenie liczby prób odgadnięcia klucza LSKF wymuszane przez SE.
Jeśli urządzenie nie ma SE, zamiast tego LockSettingsService
używa rozciągniętego klucza LSKF jako hasła Gatekeeper. LockSettingsService
następnie szyfruje syntetyczne hasło 2 razy: najpierw za pomocą klucza programowego pochodzącego z rozszerzonego klucza LSKF i skrótu pliku, który można usunąć, a potem za pomocą klucza magazynu kluczy powiązanego z rejestracją w usłudze Gatekeeper. Zapewnia to ograniczenie liczby prób odgadnięcia klucza LSKF wymuszane przez TEE.
Gdy LSKF zostanie zmieniony, LockSettingsService
usuwa wszystkie informacje powiązane z powiązaniem syntetycznego hasła ze starym LSKF. Na urządzeniach, które obsługują klucze Weaver lub klucze Keystore odporne na przywracanie, gwarantuje to bezpieczne usunięcie starego powiązania. Dlatego opisane tutaj zabezpieczenia są stosowane nawet wtedy, gdy użytkownik nie ma LSKF.