Identificadores de dispositivos

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:

  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 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 activa SecurityException . 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 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 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:

  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 del tipo byte [].
  3. 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()));
    }
    
  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>