Идентификаторы устройств

В Android 10 изменены разрешения для идентификаторов устройств, так что все идентификаторы устройств теперь защищены разрешением READ_PRIVILEGED_PHONE_STATE . До Android 10 постоянные идентификаторы устройств (IMEI/MEID, IMSI, SIM и серийный номер сборки) были защищены разрешением READ_PHONE_STATE во время выполнения. Разрешение READ_PRIVILEGED_PHONE_STATE предоставляется только приложениям, подписанным с помощью ключа платформы, и привилегированным системным приложениям.

Дополнительную информацию о новых требованиях к разрешениям можно найти на страницах Javadoc для TelephonyManager.java и Build.java .

Это изменение затрагивает следующие API:

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Сборка#getSerial

Доступ к приложениям оператора связи без разрешения READ_PRIVILEGED_PHONE_STATE

Предварительно загруженные операторские приложения, которые не соответствуют разрешению READ_PRIVILEGED_PHONE_STATE , могут реализовать один из вариантов, указанных в таблице ниже.

Вариант Описание Ограничения
Привилегии оператора UICC Платформа Android загружает сертификаты, хранящиеся в UICC, и предоставляет приложениям, подписанным этими сертификатами, разрешение на вызов специальных методов. У старых операторов связи имеется большое, устоявшееся количество SIM-карт, которое нелегко обновить. Кроме того, операторы связи, у которых нет авторских прав на новые SIM-карты (например, MVNO, у которых есть SIM-карты, выпущенные операторами мобильной связи), не могут добавлять или обновлять сертификаты на SIM-картах.
Список разрешенных OEM-производителей OEM-производители могут использовать OP_READ_DEVICE_IDENTIFIER для предоставления идентификаторов устройств приложениям операторов связи, включенным в разрешенный список. Это решение не масштабируется для всех операторов связи.
Код присвоения типа (TAC) Используйте метод getTypeAllocationCode , представленный в Android 10, чтобы предоставить TAC, который возвращает информацию о производителе и модели. Информация в TAC недостаточна для идентификации конкретного устройства.
MSISDN Операторы связи могут использовать номер телефона (MSISDN), доступный в TelephonyManager с группой разрешений PHONE , для поиска IMEI в своих серверных системах. Это требует значительных инвестиций от перевозчиков. Операторам связи, которые сопоставляют свои сетевые ключи с помощью IMSI , требуются значительные технические ресурсы для перехода на MSISDN .

Все приложения оператора связи могут получить доступ к идентификаторам устройств, обновив файл CarrierConfig.xml хешем сертификата подписи приложения оператора связи. Когда приложение оператора связи вызывает метод для чтения привилегированной информации, платформа ищет совпадение хеша сертификата подписи приложения (подпись сертификата SHA-1 или SHA-256) в файле CarrierConfig.xml . Если совпадение найдено, запрошенная информация возвращается. Если совпадение не найдено, возвращается исключение безопасности.

Чтобы реализовать это решение, операторы связи ДОЛЖНЫ выполнить следующие шаги:

  1. Обновите CarrierConfig.xml , указав хэш сертификата подписи приложения оператора связи, и отправьте исправление .
  2. Попросите OEM-производителей обновить свою сборку с помощью QPR1+ (рекомендуется) ИЛИ эти необходимые исправления платформы и исправление, содержащее обновленный файл CarrierConfig.xml из шага 1 выше.

Выполнение

Обновите белый список привилегированных разрешений, чтобы предоставить разрешение READ_PRIVILEGED_PHONE_STATE тем привилегированным приложениям, которым требуется доступ к идентификаторам устройств.

Дополнительную информацию о внесении в белый список см. в разделе «Белый список привилегированных разрешений» .

Чтобы вызвать затронутые API, приложение должно соответствовать одному из следующих требований:

  • Если приложение является предварительно загруженным привилегированным приложением, ему необходимо разрешение READ_PRIVILEGED_PHONE_STATE , объявленное в AndroidManifest.xml. Приложению также необходимо внести это привилегированное разрешение в белый список.
  • Для приложений, распространяемых через Google Play, требуются права оператора связи. Узнайте больше о предоставлении привилегий оператора на странице «Привилегии оператора UICC» .
  • Приложение владельца устройства или профиля, которому предоставлено разрешение READ_PHONE_STATE .

Приложение, не отвечающее ни одному из этих требований, ведет себя следующим образом:

  • Если приложение ориентировано на pre-Q и ему не предоставлено разрешение READ_PHONE_STATE , срабатывает SecurityException . это текущее поведение pre-Q, поскольку это разрешение требуется для вызова этих API.
  • Если приложение ориентировано на pre-Q и ему предоставлено разрешение READ_PHONE_STATE , оно получает нулевое значение для всех API-интерфейсов TelephonyManager и Build.UNKNOWN для метода Build#getSerial .
  • Если приложение предназначено для Android 10 или более поздней версии и не соответствует ни одному из новых требований, оно получает исключение SecurityException.

Валидация и тестирование

Набор тестов совместимости (CTS) включает тесты для проверки ожидаемого поведения доступа к идентификатору устройства для приложений с привилегиями оператора связи, владельцев устройств и профилей, а также для тех приложений, которые, как ожидается, не будут иметь доступа к идентификаторам устройств.

Следующие тесты CTS специфичны для этой функции.

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

Часто задаваемые вопросы

Сколько приложений можно внести в список разрешенных в CarrierConfig.xml для данного (MCC, MNC)?

Количество хешей сертификатов, включенных в массив, не ограничено.

Какие параметры CarrierConfig в CarrierConfig.xml мне нужно использовать, чтобы приложение было внесено в белый список?

Используйте следующий элемент конфигурации верхнего уровня в конкретном CarrierConfig.xml из настраиваемых вами параметров AOSP:

<string-array name="carrier_certificate_string_array" num="2">
    <item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/>
    <item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/>
</string-array>

Есть ли базовый шаблон CarrierConfig, который я могу использовать?

Используйте следующий шаблон. Его следует добавить к соответствующему активу .

<?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>

Должна ли SIM-карта оператора быть в устройстве для доступа к идентификаторам устройства?

Используемый файл CarrierConfig.xml определяется на основе вставленной в данный момент SIM-карты. Это означает, что если приложение оператора X попытается получить права доступа, когда вставлена ​​SIM-карта оператора Y, устройство не найдет совпадение с хешем и вернет исключение безопасности.

На устройствах с несколькими SIM-картами оператор №1 имеет права доступа только для SIM-карты №1 и наоборот.

Как операторы связи преобразуют сертификат подписи приложения в хэш?

Чтобы преобразовать сертификаты подписи в хеш перед добавлением их в CarrierConfig.xml , выполните следующие действия:

  1. Преобразуйте подпись сертификата подписи в массив байтов с помощью toByteArray .
  2. Используйте MessageDigest для преобразования массива байтов в хэш типа byte[].
  3. Преобразуйте хэш из byte[] в формат шестнадцатеричной строки. Пример см. в 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. Если certHashes представляет собой массив размером 2 со значениями 12345 и 54321 , добавьте следующее в файл конфигурации оператора связи.

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