Android 10 zmienia uprawnienia do identyfikatorów urządzeń, dzięki czemu wszystkie identyfikatory urządzeń są teraz chronione uprawnieniem READ_PRIVILEGED_PHONE_STATE
. W wersjach wcześniejszych niż Android 10 trwałe identyfikatory urządzeń (IMEI/MEID, IMSI, SIM i numer seryjny kompilacji) były chronione uprawnieniami wykonawczymi READ_PHONE_STATE
. Uprawnienie READ_PRIVILEGED_PHONE_STATE
jest przyznawane tylko aplikacjom podpisanym kluczem platformy i uprzywilejowanym aplikacjom systemowym.
Więcej informacji na temat nowych wymagań dotyczących uprawnień można znaleźć na stronach Javadoc dla TelephonyManager.java i Build.java .
Ta zmiana dotyczy następujących interfejsów API:
- TelephonyManager#getDeviceId
- TelephonyManager#getImei
- TelephonyManager#getMeid
- TelephonyManager#getSimSerialNumber
- TelephonyManager#getSubscriberId
- Zbuduj#pobierzSerial
Dostęp dla aplikacji operatora bez uprawnień READ_PRIVILEGED_PHONE_STATE
Fabrycznie załadowane aplikacje operatora, które nie kwalifikują się do uprawnienia READ_PRIVILEGED_PHONE_STATE
, mogą zaimplementować jedną z opcji z poniższej tabeli.
Opcja | Opis | Ograniczenia |
---|---|---|
Uprawnienia przewoźnika UICC | Platforma Android ładuje certyfikaty przechowywane w UICC i zezwala aplikacjom podpisanym tymi certyfikatami na wykonywanie wywołań specjalnych metod. | Starsi operatorzy mają dużą, ustaloną populację kart SIM, której nie można łatwo zaktualizować. Ponadto operatorzy, którzy nie mają praw autorskich do nowych kart SIM (na przykład MVNO, którzy mają karty SIM wydane przez MNO) nie mogą dodawać ani aktualizować certyfikatów na kartach SIM. |
Lista dozwolonych OEM | Producenci OEM mogą używać OP_READ_DEVICE_IDENTIFIER do udostępniania identyfikatorów urządzeń aplikacjom operatorów z listy dozwolonych. | To rozwiązanie nie jest skalowalne dla wszystkich operatorów. |
Kod przydziału typu (TAC) | Użyj metody getTypeAllocationCode wprowadzonej w Androidzie 10, aby udostępnić TAC, który zwraca informacje o producencie i modelu. | Informacje zawarte w TAC są niewystarczające do zidentyfikowania konkretnego urządzenia. |
MSISDN | Operatorzy mogą korzystać z numeru telefonu (MSISDN) dostępnego w TelephonyManager z grupą uprawnień PHONE , aby wyszukać numer IMEI w swoich systemach zaplecza. | Wymaga to od przewoźników znacznych inwestycji. Operatorzy mapujący swoje klucze sieciowe za pomocą IMSI wymagają znacznych zasobów technicznych, aby przełączyć się na MSISDN . |
Wszystkie aplikacje operatora mogą uzyskiwać dostęp do identyfikatorów urządzeń, aktualizując plik CarrierConfig.xml
za pomocą skrótu certyfikatu podpisywania aplikacji operatora. Gdy aplikacja przewoźnika wywołuje metodę odczytywania informacji uprzywilejowanych, platforma szuka dopasowania skrótu certyfikatu podpisywania aplikacji (podpis SHA-1 lub SHA-256 certyfikatu) w pliku CarrierConfig.xml
. Jeśli zostanie znalezione dopasowanie, zwracane są żądane informacje. Jeśli nie zostanie znalezione dopasowanie, zwracany jest wyjątek bezpieczeństwa.
Aby wdrożyć to rozwiązanie, przewoźnicy MUSZĄ wykonać następujące kroki:
- Zaktualizuj plik
CarrierConfig.xml
za pomocą skrótu certyfikatu podpisywania aplikacji przewoźnika i prześlij poprawkę . - Poproś producentów OEM o zaktualizowanie ich kompilacji za pomocą QPR1+ (zalecane) LUB tych wymaganych poprawek platformy i poprawki zawierającej zaktualizowany plik
CarrierConfig.xml
z kroku 1 powyżej.
Realizacja
Zaktualizuj swoją listę dozwolonych uprawnień uprzywilejowanych, aby przyznać uprawnienie READ_PRIVILEGED_PHONE_STATE
tym aplikacjom uprzywilejowanym, które wymagają dostępu do identyfikatorów urządzeń.
Aby dowiedzieć się więcej o umieszczaniu na liście dozwolonych, zapoznaj się z artykułem Lista dozwolonych z uprawnieniami uprzywilejowanymi .
Aby wywołać interfejsy API, których dotyczy problem, aplikacja musi spełniać jedno z poniższych wymagań:
- Jeśli aplikacja jest wstępnie załadowaną aplikacją uprzywilejowaną, potrzebuje uprawnienia
READ_PRIVILEGED_PHONE_STATE
zadeklarowanego w pliku AndroidManifest.xml. Aplikacja musi również umieścić to uprzywilejowane uprawnienie na liście dozwolonych. - Aplikacje dostarczane przez Google Play wymagają uprawnień operatora. Dowiedz się więcej o przyznawaniu uprawnień przewoźnika na stronie UICC Carrier Privileges .
- Aplikacja właściciela urządzenia lub profilu, której przyznano uprawnienie
READ_PHONE_STATE
.
Aplikacja, która nie spełnia żadnego z tych wymagań, zachowuje się następująco:
- Jeśli aplikacja jest kierowana na pre-Q i nie ma przyznanego uprawnienia
READ_PHONE_STATE
, wyzwalany jest wyjątekSecurityException
. jest to obecne zachowanie sprzed wersji Q, ponieważ to uprawnienie jest wymagane do wywołania tych interfejsów API. - Jeśli aplikacja jest przeznaczona na pre-Q i ma przyznane uprawnienie
READ_PHONE_STATE
, otrzymuje wartość null dla wszystkich interfejsów API TelephonyManager iBuild.UNKNOWN
dla metodyBuild#getSerial
. - Jeśli aplikacja jest przeznaczona dla systemu Android 10 lub nowszego i nie spełnia żadnego z nowych wymagań, otrzymuje SecurityException.
Walidacja i testowanie
Zestaw testów zgodności (CTS) obejmuje testy weryfikujące oczekiwane zachowanie dostępu do identyfikatora urządzenia dla aplikacji z uprawnieniami operatora, właścicielami urządzeń i profili oraz tych aplikacji, które nie mają dostępu do identyfikatorów urządzeń.
Następujące testy CTS są specyficzne dla tej funkcji.
cts-tradefed run cts -m CtsCarrierApiTestCases -t android.carrierapi.cts.CarrierApiTest
cts-tradefed run cts -m CtsTelephonyTestCases -t android.telephony.cts.TelephonyManagerTest
cts-tradefed run cts -m CtsTelephony3TestCases
cts-tradefed run cts -m CtsPermissionTestCases -t android.permission.cts.TelephonyManagerPermissionTest
cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCanGetDeviceIdentifiers
cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCanGetDeviceIdentifiers
cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCannotGetDeviceIdentifiersWithoutPermission
cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission
Często zadawane pytania
Ile aplikacji można umieścić na liście dozwolonych w CarrierConfig.xml
dla danego (MCC, MNC)?
Nie ma ograniczeń co do liczby skrótów certyfikatów zawartych w tablicy.
Których parametrów CarrierConfig w CarrierConfig.xml
muszę użyć, aby aplikacja znalazła się na liście dozwolonych?
Użyj następującego elementu konfiguracji najwyższego poziomu w określonym CarrierConfig.xml
spośród konfigurowanych opcji AOSP:
<string-array name="carrier_certificate_string_array" num="2"> <item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/> <item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/> </string-array>
Czy istnieje podstawowy szablon CarrierConfig, którego mogę użyć?
Skorzystaj z poniższego szablonu. Należy to dodać do odpowiedniego zasobu .
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <carrier_config> <string-array name="carrier_certificate_string_array" num="1"> <item value="CERTIFICATE_HASH_HERE"/> </string-array> </carrier_config>
Czy karta SIM operatora musi znajdować się w urządzeniu, aby uzyskać dostęp do identyfikatorów urządzeń?
Używany plik CarrierConfig.xml
jest określany na podstawie aktualnie włożonej karty SIM. Oznacza to, że jeśli aplikacja operatora X spróbuje uzyskać uprawnienia dostępu, gdy włożona jest karta SIM operatora Y, urządzenie nie znajdzie dopasowania dla skrótu i zwróci wyjątek bezpieczeństwa.
Na urządzeniach z wieloma kartami SIM operator nr 1 ma uprawnienia dostępu tylko do karty SIM nr 1 i odwrotnie.
W jaki sposób operatorzy konwertują certyfikat podpisywania aplikacji na skrót?
Aby przekonwertować certyfikaty podpisywania na skrót przed dodaniem ich do CarrierConfig.xml
, wykonaj następujące czynności:
- Konwertuj podpis certyfikatu podpisywania na tablicę bajtów, używając
toByteArray
. - Użyj
MessageDigest
aby przekonwertować tablicę bajtów na hash typu byte[]. Konwertuj skrót z bajtu [] na format ciągu szesnastkowego. Aby zapoznać się z przykładem, zobacz
IccUtils.java
.List<String> certHashes = new ArrayList<>(); PackageInfo pInfo; // Carrier app PackageInfo MessageDigest md = MessageDigest.getInstance("SHA-256"); for (Signature signature : pInfo.signatures) { certHashes.add(bytesToHexString(md.digest(signature.toByteArray())); }
Jeśli
certHashes
jest tablicą o rozmiarze2
z wartościami12345
i54321
, dodaj następujące elementy do pliku konfiguracyjnego przewoźnika.<string-array name="carrier_certificate_string_array" num="2"> <item value="12345"/> <item value="54321"/> </string-array>