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ądzeń (IMEI/MEID, IMSI, SIM i numer seryjny kompilacji) były chronione przez uprawnienia w czasie działania (aplikacji) READ_PHONE_STATE. 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.java i Build.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 uprawnienia 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 Androida wczytuje certyfikaty przechowywane na karcie UICC i przyznaje aplikacjom podpisanym tymi certyfikatami uprawnienia do wywoływania metod specjalnych. 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ć OP_READ_DEVICE_IDENTIFIER do udostępniania identyfikatorów urządzeń aplikacjom operatorów umieszczonym na liście 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 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 TelephonyManager z grupą uprawnień PHONE, aby wyszukiwać numer IMEI w swoich systemach backendowych. Wymaga to od operatoró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 podpisu aplikacji operatora. Gdy aplikacja operatora wywołuje metodę odczytu informacji o podwyższonych uprawnieniach, platforma szuka w pliku CarrierConfig.xml haszu certyfikatu podpisu 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. Zaktualizuj CarrierConfig.xml, podając hash certyfikatu podpisu aplikacji operatora, i prześlij poprawkę.
  2. Poproś producentów OEM o zaktualizowanie kompilacji do wersji QPR-1 lub nowszej (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ń, aby przyznać uprawnienie READ_PRIVILEGED_PHONE_STATE aplikacjom z uprawnieniami, które wymagają dostępu do identyfikatorów urządzeń.

Więcej informacji o umieszczaniu na liście dozwolonych znajdziesz w artykule Umieszczanie na liście dozwolonych uprawnień uprzywilejowanych.

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ć zadeklarowane uprawnienie READ_PRIVILEGED_PHONE_STATE 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 kierowana na wersję Androida starszą niż Q i nie ma przyznanych uprawnień READ_PHONE_STATE, wywoływane jest zdarzenie SecurityException. Jest to obecne zachowanie w przypadku wersji Androida starszych niż Q, ponieważ te uprawnienia są wymagane do wywoływania tych interfejsów API.
  • Jeśli aplikacja jest przeznaczona na urządzenia z Androidem starszym niż Q i ma przyznane uprawnienie READ_PHONE_STATE, otrzymuje wartość null w przypadku wszystkich interfejsów API TelephonyManager i Build.UNKNOWN w przypadku metody Build#getSerial.
  • 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ądzeń.

Te testy CTS dotyczą 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)?

Liczba skrótów certyfikatów w tablicy jest nieograniczona.

Które parametry CarrierConfig w CarrierConfig.xml muszę zastosować, aby aplikacja została dodana do listy dozwolonych?

Użyj tego elementu konfiguracji najwyższego poziomu w konkretnym pliku CarrierConfig.xml z 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 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 karty SIM, która jest obecnie włożona. 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 na odwrót.

Jak operatorzy przekształcają certyfikat podpisywania aplikacji na hasz?

Aby przekształcić certyfikaty podpisywania w wartość skrótu przed dodaniem ich do CarrierConfig.xml, wykonaj te czynności:

  1. Przekonwertuj podpis certyfikatu podpisywania na tablicę bajtów za pomocą funkcji toByteArray.
  2. Użyj MessageDigest, aby przekonwertować tablicę bajtów na skrót typu 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ą 12345 i 54321, dodaj do pliku konfiguracyjnego operatora te informacje:

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