Identyfikatory urządzeń

Android 10 zmienia uprawnienia do identyfikatorów urządzeń, tak aby wszystkie identyfikatory urządzeń były teraz chronione przez uprawnienie READ_PRIVILEGED_PHONE_STATE. Przed Androidem 10 trwałe identyfikatory urządzenia (IMEI/MEID, IMSI, SIM i numer seryjny kompilacji) były chronione przez READ_PHONE_STATE uprawnienia w czasie działania. Uprawnienie READ_PRIVILEGED_PHONE_STATE jest przyznawane tylko aplikacjom podpisanym kluczem platformy i aplikacjom systemowym z uprawnieniami.

Więcej informacji o nowych wymaganiach dotyczących uprawnień znajdziesz na stronach Javadoc dla plików TelephonyManager.javaBuild.java.

Ta zmiana dotyczy tych interfejsów API:

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Build#getSerial

Dostęp dla aplikacji operatora bez uprawnień READ_PRIVILEGED_PHONE_STATE

Wstępnie załadowane aplikacje operatora, które nie kwalifikują się do uzyskania uprawnienia READ_PRIVILEGED_PHONE_STATE, mogą wdrożyć jedną z opcji podanych w tabeli poniżej.

Opcja Opis Ograniczenia
Uprawnienia operatora UICC Platforma Android wczytuje certyfikaty przechowywane na karcie UICC i przyznaje uprawnienia aplikacjom podpisanym tymi certyfikatami do wywoływania specjalnych metod. Tradycyjni operatorzy mają dużą, ustaloną bazę kart SIM, której nie można łatwo zaktualizować. Operatorzy, którzy nie mają praw do tworzenia nowych kart SIM (np. MVNO, które mają karty SIM wydane przez MNO), nie mogą też dodawać ani aktualizować certyfikatów na kartach SIM.
Lista dozwolonych producentów OEM Producenci OEM mogą używać interfejsu OP_READ_DEVICE_IDENTIFIER do udostępniania identyfikatorów urządzeń aplikacjom operatorów, które znajdują się na liście dozwolonych. To rozwiązanie nie jest skalowalne dla wszystkich przewoźnikó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 urządzenia. Informacje w TAC są niewystarczające do identyfikacji konkretnego urządzenia.
(numer) MSISDN Operatorzy mogą używać numeru telefonu (MSISDN) dostępnego w sekcji TelephonyManager z grupą uprawnień PHONE, aby wyszukiwać numer IMEI w swoich systemach backendowych. Wymaga to od przewoźników znacznych inwestycji. Operatorzy, którzy mapują klucze sieciowe za pomocą IMSI, potrzebują znacznych zasobów technicznych, aby przejść na MSISDN.

Wszystkie aplikacje operatorów mogą uzyskać dostęp do identyfikatorów urządzeń, aktualizując plik CarrierConfig.xml za pomocą haszu certyfikatu podpisywania aplikacji operatora. Gdy aplikacja operatora wywołuje metodę odczytu informacji o podwyższonych uprawnieniach, platforma szuka w pliku CarrierConfig.xml haszu certyfikatu podpisywania aplikacji (podpisu SHA-1 lub SHA-256 certyfikatu). Jeśli znajdziemy dopasowanie, zwrócimy żądane informacje. Jeśli nie zostanie znalezione dopasowanie, zwracany jest wyjątek związany z bezpieczeństwem.

Aby wdrożyć to rozwiązanie, przewoźnicy MUSZĄ wykonać te czynności:

  1. Update CarrierConfig.xml z haszem certyfikatu podpisu aplikacji operatora i prześlij poprawkę.
  2. Poproś producentów OEM o zaktualizowanie kompilacji do wersji QPR1+ (zalecane) LUB o zastosowanie tych wymaganych poprawek platformy i poprawki zawierającej zaktualizowany plik CarrierConfig.xml z kroku 1 powyżej.

Implementacja

Zaktualizuj listę dozwolonych uprawnień uprzywilejowanych, aby przyznać uprawnienie READ_PRIVILEGED_PHONE_STATE uprzywilejowanym aplikacjom, które wymagają dostępu do identyfikatorów urządzeń.

Więcej informacji o umieszczaniu na liście dozwolonych znajdziesz w artykule Umieszczanie uprawnień z dostępem do informacji poufnych na liście dozwolonych.

Aby wywołać interfejsy API, których dotyczy problem, aplikacja musi spełniać jedno z tych wymagań:

  • Jeśli aplikacja jest preinstalowaną aplikacją z uprawnieniami, musi mieć uprawnienie READ_PRIVILEGED_PHONE_STATE zadeklarowane w pliku AndroidManifest.xml. Aplikacja musi też mieć przyznany dostęp do tego uprawnienia.
  • Aplikacje dostarczane za pomocą Google Play wymagają uprawnień operatora. Więcej informacji o przyznawaniu uprawnień operatora znajdziesz na stronie Uprawnienia operatora UICC.
  • Aplikacja właściciela urządzenia lub profilu, która ma przyznane uprawnienie READ_PHONE_STATE.

Aplikacja, która nie spełnia żadnego z tych wymagań, zachowuje się w ten sposób:

  • Jeśli aplikacja jest przeznaczona na urządzenia z Androidem starszym niż Q i nie ma przyznanego uprawnienia READ_PHONE_STATE, wywoływane jest zdarzenie SecurityException. Jest to obecne zachowanie w przypadku urządzeń z Androidem starszym niż Q, ponieważ to uprawnienie jest wymagane do wywoływania tych interfejsów API.
  • Jeśli aplikacja jest przeznaczona na wersje starsze niż Q i ma przyznane uprawnienie READ_PHONE_STATE, w przypadku wszystkich interfejsów API klasy TelephonyManager otrzymuje wartość null, a w przypadku metody Build#getSerial – wartość Build.UNKNOWN.
  • Jeśli aplikacja jest kierowana na Androida 10 lub nowszego i nie spełnia żadnego z nowych wymagań, otrzymuje wyjątek SecurityException.

Weryfikacja i testowanie

Pakiet testów zgodności (CTS) zawiera testy weryfikujące oczekiwane zachowanie dostępu do identyfikatora urządzenia w przypadku aplikacji z uprawnieniami operatora, właścicieli urządzeń i profili oraz aplikacji, które nie powinny mieć dostępu do identyfikatorów urządzenia.

Te 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

Najczęstsze pytania

Ile aplikacji można dodać do listy dozwolonych w CarrierConfig.xml dla danego (MCC, MNC)?

Nie ma ograniczenia liczby skrótów certyfikatów w tablicy.

Których parametrów CarrierConfig w CarrierConfig.xml muszę użyć, aby aplikacja została dodana do listy dozwolonych?

Użyj tego elementu konfiguracji najwyższego poziomu w ramach konkretnego elementu CarrierConfig.xml z opcji AOSP, które konfigurujesz:

<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 tego szablonu. Należy go dodać do odpowiedniego komponentu.

<?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 można było uzyskać dostęp do identyfikatorów urządzenia?

Używana CarrierConfig.xml zależy od włożonej karty SIM. Oznacza to, że jeśli aplikacja operatora X spróbuje uzyskać uprawnienia dostępu, gdy w urządzeniu jest włożona karta SIM operatora Y, urządzenie nie znajdzie dopasowania do skrótu i zwróci wyjątek bezpieczeństwa.

Na urządzeniach z wieloma kartami SIM operator 1 ma uprawnienia dostępu tylko do karty SIM 1 i odwrotnie.

Jak operatorzy konwertują certyfikat podpisywania aplikacji na hash?

Aby przekonwertować certyfikaty podpisywania na skrót przed dodaniem ich do CarrierConfig.xml, wykonaj te czynności:

  1. Skonwertuj podpis certyfikatu podpisywania na tablicę bajtów za pomocą funkcji toByteArray.
  2. Użyj MessageDigest, aby przekonwertować tablicę bajtów na hash w typie byte[].
  3. Przekonwertuj skrót z byte[] na ciąg szesnastkowy. Przykład znajdziesz w sekcji 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()));
    }
  4. Jeśli certHashes to tablica o rozmiarze 2 z wartością 1234554321, dodaj do pliku konfiguracji operatora te informacje:

    <string-array name="carrier_certificate_string_array" num="2">
        <item value="12345"/>
        <item value="54321"/>
    </string-array>