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 con el 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 de 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
- Administrador de telefonía#getImei
- Administrador de telefonía#getMeid
- TelephonyManager#getSimSerialNumber
- TelephonyManager#getSubscriberId
- Construir#getSerial
Acceso para aplicaciones de operadores sin el permiso READ_PRIVILEGED_PHONE_STATE
Las aplicaciones de operadores precargadas que no califican para el permiso READ_PRIVILEGED_PHONE_STATE
pueden implementar una de las opciones de la siguiente tabla.
Opción | Descripción | Limitaciones |
---|---|---|
Privilegios del transportista UICC | La plataforma Android carga los 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 población SIM grande y establecida, que no es fácil de actualizar. Además, los operadores que no tienen derechos de autor para nuevas SIM (por ejemplo, MVNO que tienen SIM emitidas por MNO) no pueden agregar ni actualizar certificados en las SIM. |
Lista de permitidos de OEM | Los OEM pueden usar OP_READ_DEVICE_IDENTIFIER para proporcionar identificadores de dispositivos a las aplicaciones de operadores incluidas en la lista de permitidos. | Esta solución no es escalable para todos los operadores. |
Escriba el código de asignación (TAC) | Usa el método getTypeAllocationCode , introducido en Android 10, para exponer el TAC que devuelve la información del fabricante y el 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 mapean sus claves de red usando IMSI requieren recursos técnicos significativos 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 con el 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 permitidos 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 la lista blanca, 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 en la lista de permitidos este permiso privilegiado. - Las aplicaciones entregadas a través de Google Play necesitan privilegios de operador. Obtenga más información sobre cómo otorgar privilegios de transportistas en la página de privilegios de transportistas de la UICC .
- Una aplicación de propietario de perfil o dispositivo 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 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 se dirige a 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á destinada a Android 10 o superior y no cumple ninguno de los nuevos requisitos, recibe una SecurityException.
Validación y prueba
El conjunto de pruebas de compatibilidad (CTS) incluye pruebas para verificar el comportamiento esperado de acceso al identificador del dispositivo para aplicaciones con privilegios de operador, propietarios de dispositivos y perfiles, y aquellas aplicaciones que se espera que no tengan acceso a los identificadores de dispositivos.
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 de permitidos 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 se incluya en la lista de permitidos?
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>
¿Hay 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 que se inserta 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 los 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 mediante
toByteArray
. - Utilice
MessageDigest
para convertir la matriz de bytes en un hash de tipo byte[]. Convierta el hash de byte[] en 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>