Identyfikatory urządzeń

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:

  1. Zaktualizuj plik CarrierConfig.xml za pomocą skrótu certyfikatu podpisywania aplikacji przewoźnika i prześlij poprawkę .
  2. 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ątek SecurityException . 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 i Build.UNKNOWN dla metody Build#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:

  1. Konwertuj podpis certyfikatu podpisywania na tablicę bajtów, używając toByteArray .
  2. Użyj MessageDigest aby przekonwertować tablicę bajtów na hash typu byte[].
  3. 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()));
    }
    
  4. Jeśli certHashes jest tablicą o rozmiarze 2 z wartościami 12345 i 54321 , 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>