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:
- Менеджер телефонии#getDeviceId
- TelephonyManager#getImei
- ТелефонияМенеджер#getMeid
- TelephonyManager#getSimSerialNumber
- Менеджер телефонии#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
. Если совпадение найдено, запрашиваемая информация возвращается. Если совпадений не найдено, возвращается исключение безопасности.
Чтобы реализовать это решение, операторы связи ДОЛЖНЫ выполнить следующие шаги:
- Обновите
CarrierConfig.xml
, указав хэш сертификата подписи приложения-перевозчика, и отправьте исправление . - Попросите 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
. это текущее поведение до 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
, выполните следующие действия:
- Преобразуйте подпись сертификата подписи в массив байтов, используя
toByteArray
. - Используйте
MessageDigest
для преобразования массива байтов в хэш типа byte[]. Преобразуйте хэш из 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())); }
Если
certHashes
— это массив размера2
со значениями12345
и54321
, добавьте следующее в файл конфигурации оператора связи.<string-array name="carrier_certificate_string_array" num="2"> <item value="12345"/> <item value="54321"/> </string-array>