Android 10 cambia los permisos para los identificadores de dispositivos para que todos los identificadores de dispositivos estén ahora protegidos por el permiso READ_PRIVILEGED_PHONE_STATE
. Antes de Android 10, los identificadores de dispositivos persistentes (IMEI / MEID, IMSI, SIM y serie de compilación) estaban protegidos detrás del permiso de tiempo de ejecución READ_PHONE_STATE
. El permiso READ_PRIVILEGED_PHONE_STATE
solo se otorga a las aplicaciones firmadas con la clave de la plataforma y las aplicaciones del sistema privilegiadas.
Puede encontrar más información sobre los nuevos requisitos de permisos en las páginas de Javadoc para TelephonyManager.java y Build.java .
Este cambio afecta a las siguientes API:
- TelephonyManager # getDeviceId
- TelephonyManager # getImei
- TelephonyManager # getMeid
- TelephonyManager # getSimSerialNumber
- TelephonyManager # getSubscriberId
- Compilación # getSerial
Acceso para aplicaciones de operador sin permiso READ_PRIVILEGED_PHONE_STATE
Las aplicaciones de operador precargadas que no califican para el permiso READ_PRIVILEGED_PHONE_STATE
pueden implementar una de las opciones en la siguiente tabla.
Opción | Descripción | Limitaciones |
---|---|---|
Privilegios de portador de UICC | La plataforma Android carga certificados almacenados en la UICC y otorga permiso a las aplicaciones firmadas por estos certificados para realizar llamadas a métodos especiales. | Los operadores heredados tienen una gran población de SIM establecida, que no es fácilmente actualizable. Además, los operadores que no tienen derechos de autor sobre nuevas SIM (por ejemplo, MVNO que tienen SIM emitidas por MNO) no pueden agregar ni actualizar certificados en las SIM. |
Lista blanca de OEM | Los OEM pueden usar OP_READ_DEVICE_IDENTIFIER para proporcionar identificadores de dispositivo a las aplicaciones de los operadores incluidos en la lista blanca. | Esta solución no es escalable para todos los operadores. |
Tipo de código de asignación (TAC) | Utilice el método getTypeAllocationCode , introducido en Android 10, para exponer el TAC que devuelve la información del fabricante y del modelo. | La información en el TAC es inadecuada para identificar un dispositivo específico. |
MSISDN | Los operadores pueden usar el número de teléfono (MSISDN), disponible en TelephonyManager con el grupo de permisos PHONE , para buscar el IMEI en sus sistemas backend. | Esto requiere una inversión significativa para los transportistas. Los operadores que asignan sus claves de red mediante IMSI requieren importantes recursos técnicos para cambiar a MSISDN . |
Todas las aplicaciones del operador pueden acceder a los identificadores de dispositivos actualizando el archivo CarrierConfig.xml
con el hash del certificado de firma de la aplicación del operador. Cuando la aplicación del operador llama a un método para leer información privilegiada, la plataforma busca una coincidencia del hash del certificado de firma de la aplicación (firma SHA-1 o SHA-256 del certificado) en el archivo CarrierConfig.xml
. Si se encuentra una coincidencia, se devuelve la información solicitada. Si no se encuentra ninguna coincidencia, se devuelve una excepción de seguridad.
Para implementar esta solución, los transportistas DEBEN seguir estos pasos:
- Actualice
CarrierConfig.xml
con el hash del certificado de firma de la aplicación del operador y envíe un parche . - Solicite a los OEM que actualicen su compilación con QPR1 + (recomendado) O estos parches de plataforma necesarios y el parche que contiene el archivo
CarrierConfig.xml
actualizado del paso 1 anterior.
Implementación
Actualice su lista blanca de permisos privilegiados para otorgar el permiso READ_PRIVILEGED_PHONE_STATE
a aquellas aplicaciones privilegiadas que requieren acceso a identificadores de dispositivos.
Para obtener más información sobre las listas blancas, consulte Lista blanca de permisos privilegiados .
Para invocar las API afectadas, una aplicación debe cumplir uno de los siguientes requisitos:
- Si la aplicación es una aplicación privilegiada precargada, necesita el permiso
READ_PRIVILEGED_PHONE_STATE
declarado en AndroidManifest.xml. La aplicación también debe incluir este permiso privilegiado en la lista blanca. - Las aplicaciones entregadas a través de Google Play necesitan privilegios de operador. Obtenga más información sobre cómo otorgar privilegios de operador en la página Privilegios de operador de UICC .
- Una aplicación de propietario de perfil o dispositivo a la que se le ha concedido el permiso
READ_PHONE_STATE
.
Una aplicación que no cumple con ninguno de estos requisitos tiene el siguiente comportamiento:
- Si la aplicación tiene como objetivo pre-Q y no tiene el permiso
READ_PHONE_STATE
otorgado, se activaSecurityException
. este es el comportamiento actual de pre-Q ya que se requiere este permiso para invocar estas API. - Si la aplicación tiene como objetivo pre-Q y tiene el permiso
READ_PHONE_STATE
otorgado, recibe un valor nulo para todas las API de TelephonyManager yBuild.UNKNOWN
para el métodoBuild#getSerial
. - Si la aplicación está dirigida a Android 10 o superior y no cumple con ninguno de los nuevos requisitos, recibe una SecurityException.
Validación y prueba
Compatibility Test Suite (CTS) incluye pruebas para verificar el comportamiento esperado de acceso al identificador de dispositivo para aplicaciones con privilegios de operador, propietarios de dispositivos y perfiles, y aquellas aplicaciones que se espera que no tengan acceso a identificadores de dispositivos.
Las siguientes pruebas CTS son específicas de esta función.
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
Preguntas frecuentes
¿Cuántas aplicaciones se pueden incluir en la lista blanca en CarrierConfig.xml
para un determinado (MCC, MNC)?
No hay límite para el número de hashes de certificado incluidos en la matriz.
¿Qué parámetros de CarrierConfig.xml
en CarrierConfig.xml
debo usar para que una aplicación se incluya en la lista blanca?
Utilice el siguiente elemento de configuración de nivel superior dentro del CarrierConfig.xml
específico de las opciones de AOSP que está configurando:
<string-array name="carrier_certificate_string_array" num="2"> <item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/> <item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/> </string-array>
¿Existe una plantilla básica de CarrierConfig que pueda utilizar?
Utilice la siguiente plantilla. Esto debe agregarse al activo relevante .
<?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>
¿La tarjeta SIM del operador tiene que estar en el dispositivo para acceder a los identificadores de dispositivo?
El CarrierConfig.xml
que se utiliza se determina en función de la SIM que está insertada actualmente. Esto significa que si la aplicación del operador X intenta obtener privilegios de acceso mientras se inserta la SIM del operador Y, el dispositivo no encontrará una coincidencia para el hash y devolverá una excepción de seguridad.
En dispositivos con múltiples SIM, el operador n. ° 1 solo tiene privilegios de acceso para la SIM n. ° 1 y viceversa.
¿Cómo convierten los operadores el certificado de firma de una aplicación en un hash?
Para convertir certificados de firma en un hash antes de agregarlos a CarrierConfig.xml
, haga lo siguiente:
- Convierta la firma del certificado de firma en una matriz de bytes usando
toByteArray
. - Utilice
MessageDigest
para convertir la matriz de bytes en un hash del tipo byte []. Convierta el hash del byte [] a un formato de cadena hexadecimal. Para obtener un ejemplo, consulte
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())); }
Si
certHashes
es una matriz de tamaño2
con un valor de12345
y54321
, agregue lo siguiente al archivo de configuración del operador.<string-array name="carrier_certificate_string_array" num="2"> <item value="12345"/> <item value="54321"/> </string-array>