Android 10 cambia los permisos para los identificadores de dispositivos para que todos los identificadores de dispositivos ahora estén 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 aplicaciones firmadas con la clave de plataforma y aplicaciones privilegiadas del sistema.
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:
- Administrador de telefonía#getDeviceId
- Administrador de telefonía#getImei
- Administrador de telefonía#getMeid
- Administrador de telefonía#getSimSerialNumber
- Administrador de telefonía#getSubscriberId
- Compilación#getSerial
Acceso a aplicaciones de operador sin el 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 del transportista 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 tradicionales tienen una población SIM grande y establecida, que no se puede actualizar fácilmente. 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 de permitidos OEM | Los OEM pueden usar OP_READ_DEVICE_IDENTIFIER para proporcionar identificadores de dispositivos a aplicaciones de operadores incluidas en la lista permitida. | Esta solución no es escalable para todos los operadores. |
Código de asignación de tipo (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 del 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 requeridos y el parche que contiene el archivo
CarrierConfig.xml
actualizado del paso 1 anterior.
Implementación
Actualice su lista de permisos privilegiados permitidos 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 de permitidos, consulte Listas de permitidos con 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 de permitidos. - 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 la UICC .
- Una aplicación de propietario de dispositivo o perfil a la que se le ha otorgado el permiso
READ_PHONE_STATE
.
Una aplicación que no cumple ninguno de estos requisitos tiene el siguiente comportamiento:
- Si la aplicación está dirigida a pre-Q y no tiene concedido el permiso
READ_PHONE_STATE
, se activaSecurityException
. este es el comportamiento actual anterior a Q, ya que se requiere este permiso para invocar estas API. - Si la aplicación está orientada a pre-Q y tiene concedido el permiso
READ_PHONE_STATE
, 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 pruebas
El conjunto de pruebas de compatibilidad (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 dispositivo.
Las siguientes pruebas CTS son específicas de esta característica.
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 permitida en CarrierConfig.xml
para un determinado (MCC, MNC)?
No hay límite para la cantidad de hashes de certificados incluidos en la matriz.
¿Qué parámetros de CarrierConfig en CarrierConfig.xml
debo usar para que una aplicación esté incluida en la lista permitida?
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 base de CarrierConfig que pueda usar?
Utilice la siguiente plantilla. Esto debe agregarse al activo correspondiente .
<?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 SIM del operador tiene que estar en el dispositivo para acceder a los identificadores del dispositivo?
El CarrierConfig.xml
que se utiliza se determina en función de la tarjeta SIM actualmente insertada. Esto significa que si la aplicación del operador X intenta obtener privilegios de acceso mientras la tarjeta SIM del operador Y está insertada, el dispositivo no encontrará una coincidencia para el hash y devolverá una excepción de seguridad.
En dispositivos multi-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 de tipo byte[]. Convierta el hash del byte[] a un formato de cadena hexadecimal. Para ver 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>