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 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:

  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 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 activa SecurityException . 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 y Build.UNKNOWN para el método Build#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:

  1. Convierta la firma del certificado de firma en una matriz de bytes mediante toByteArray .
  2. Utilice MessageDigest para convertir la matriz de bytes en un hash de tipo byte[].
  3. 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()));
    }
    
  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>