Identificadores de dispositivos

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:

  1. Actualice CarrierConfig.xml con el hash del certificado de firma de la aplicación del operador y envíe un parche .
  2. 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 activa SecurityException . 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 y Build.UNKNOWN para el método Build#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:

  1. Convierta la firma del certificado de firma en una matriz de bytes usando toByteArray .
  2. Utilice MessageDigest para convertir la matriz de bytes en un hash de tipo byte[].
  3. 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()));
    }
    
  4. Si certHashes es una matriz de tamaño 2 con un valor de 12345 y 54321 , 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>