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

В 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
  • Build#getSerial

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

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

Вариант Описание Ограничения
Привилегии оператора связи UICC Платформа Android загружает сертификаты, хранящиеся в UICC, и предоставляет приложениям, подписанным этими сертификатами, разрешение на вызов специальных методов. У традиционных операторов связи имеется большой, устоявшийся парк SIM-карт, который сложно обновлять. Кроме того, операторы, не имеющие прав на создание новых SIM-карт (например, виртуальные операторы, использующие SIM-карты, выпущенные операторами мобильной связи), не могут добавлять или обновлять сертификаты на этих SIM-картах.
Список разрешенных 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. Попросите производителей оборудования обновить свои сборки до версии 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 , оно получает значение null для всех API TelephonyManager и Build.UNKNOWN для метода Build#getSerial .
  • Если приложение ориентировано на Android 10 или более позднюю версию и не соответствует хотя бы одному из новых требований, оно получит исключение SecurityException.

Проверка и тестирование

Набор тестов на совместимость (Compatibility Test Suite, 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>