Identyfikatory urządzeń

Android 10 zmienia uprawnienia dotyczące 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, karta SIM i numer seryjny kompilacji) były chronione za pomocą uprawnienia do działania READ_PHONE_STATE. Uprawnienie READ_PRIVILEGED_PHONE_STATE jest przyznawane tylko aplikacjom podpisanym kluczem platformy i uprzywilejowanym aplikacjom systemowym.

Więcej informacji o nowych wymaganiach dotyczących uprawnień znajdziesz na stronach Javadoc 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 zainstalowane aplikacje operatora, które nie kwalifikują się do uprawnienia READ_PRIVILEGED_PHONE_STATE mogą stosować jedną z opcji w tabeli poniżej.

Opcja Opis Ograniczenia
Uprawnienia operatora UICC Platforma Android wczytuje certyfikaty zapisane na karcie UICC i przyznaje aplikacjom podpisanym tymi certyfikatami uprawnienia do wywoływania specjalnych metod. Stare sieci mają dużą, ugruntowaną pozycję na rynku grupę użytkowników kart SIM, której nie można łatwo zaktualizować. Operatorzy, którzy nie mają praw autorskich do nowych kart SIM (np. MVNO, które mają karty SIM wydane przez MNO), nie mogą 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 operatora dodanym do listy dozwolonych. To rozwiązanie nie jest skalowalne w przypadku wszystkich operatorów.
Typ kodu przydziału (TAC) Aby uzyskać informacje o producencie i modelu, użyj metody getTypeAllocationCode, która została wprowadzona w Androidzie 10. Metoda ta umożliwia uzyskanie TAC. Informacje w TAC są niewystarczające do zidentyfikowania konkretnego urządzenia.
(numer) MSISDN Operatorzy mogą użyć numeru telefonu (MSISDN) dostępnego w grupie uprawnień TelephonyManager z uprawnieniami PHONE, aby sprawdzić numer IMEI w swoich systemach zaplecza. Wymaga to znacznych inwestycji ze strony operatorów. Operatorzy, którzy mapują swoje klucze sieciowe za pomocą IMSI, potrzebują znacznych zasobów technicznych, aby przejść na MSISDN.

Wszystkie aplikacje operatora mogą uzyskiwać dostęp do identyfikatorów urządzenia przez aktualizowanie pliku CarrierConfig.xml za pomocą hasza certyfikatu podpisywania aplikacji operatora. Gdy aplikacja operatora wywołuje metodę do odczytu uprzywilejowanych informacji, platforma szuka w pliku CarrierConfig.xml dopasowania hasza certyfikatu podpisywania aplikacji (podpis SHA-1 lub SHA-256 certyfikatu) w pliku CarrierConfig.xml. Jeśli znajdziemy dopasowanie, zwrócimy żądane informacje. Jeśli nie zostanie znalezione żadne dopasowanie, zwrócone zostanie wyłączenie zabezpieczeń.

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

  1. Zaktualizuj CarrierConfig.xml za pomocą hasha certyfikatu podpisywania aplikacji operatora i prześlij poprawkę.
  2. Poproś OEM-ów o zaktualizowanie ich wersji o poprawkę QPR1+ (zalecane) LUB te wymagane poprawki platformy oraz poprawkę zawierającą zaktualizowany plik CarrierConfig.xml z kroku 1.

Implementacja

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

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

Aby wywołać te interfejsy API, aplikacja musi spełniać jedno z tych wymagań:

  • Jeśli aplikacja jest preinstalowaną aplikacją uprzywilejowaną, musi mieć zadeklarowane uprawnienieREAD_PRIVILEGED_PHONE_STATE w pliku AndroidManifest.xml. Aplikacja musi też dodać to uprawnienie do listy dozwolonych.
  • Aplikacje dostarczane przez Google Play wymagają uprawnień operatora. Więcej informacji o przyznawaniu uprawnień operatora znajdziesz na stronie UICC Carrier Privileges (Uprawnienia operatora UICC).
  • Aplikacja właściciela urządzenia lub profilu, której przyznano uprawnienia READ_PHONE_STATE.

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

  • Jeśli aplikacja jest kierowana na urządzenia z Androidem w wersji Q i nie ma przyznanego uprawnienia READ_PHONE_STATE, uruchamia się uprawnienie SecurityException. To jest obecne zachowanie w przypadku urządzeń z Androidem w wersji Q, ponieważ to uprawnienie jest wymagane do wywołania tych interfejsów API.
  • Jeśli aplikacja jest kierowana na urządzenia z systemem Android w wersji niższej niż Q i ma przyznane uprawnienie READ_PHONE_STATE, otrzymuje wartość null dla wszystkich interfejsów API TelephonyManager i Build.UNKNOWN dla metody Build#getSerial.
  • Jeśli aplikacja jest kierowana na Androida 10 lub nowszego i nie spełnia żadnego z tych nowych wymagań, otrzymuje wyjątek SecurityException.

Weryfikacja i testowanie

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

Poniższe 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że znajdować się na liście dozwolonych w przypadku danego konta (MCK, MCN)?CarrierConfig.xml

Nie ma limitu liczby haszy 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 tego elementu konfiguracji najwyższego poziomu w szczególnym 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ć?

Użyj tego szablonu. Należy go 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 aby uzyskać dostęp do identyfikatorów urządzenia, karta SIM operatora musi znajdować się w urządzeniu?

Używana CarrierConfig.xml jest określana na podstawie aktualnie włożonej karty SIM. Oznacza to, że jeśli aplikacja operatora X próbuje uzyskać uprawnienia dostępu, gdy w urządzeniu jest włożona karta SIM operatora Y, urządzenie nie znajdzie dopasowania do hasha i zwróci wyjątek zabezpieczeń.

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

Jak operatorzy przekształcają certyfikat podpisywania aplikacji w łańcuch haszowy?

Aby przekonwertować certyfikaty podpisywania na ciągi bajtów, zanim dodasz je do CarrierConfig.xml, wykonaj te czynności:

  1. Za pomocą toByteArray przekonwertuj podpis certyfikatu podpisującego na tablicę bajtów.
  2. Użyj funkcji MessageDigest, aby przekonwertować tablicę bajtów na hasz typu byte[].
  3. Konwertuje hasz z byte[] na ciąg znaków szesnastkowych. Przykład: 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 o 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>