Identifiants des appareils

Android 10 modifie les autorisations pour les identifiants d'appareil. Désormais, tous les identifiants d'appareil sont protégés par l'autorisation READ_PRIVILEGED_PHONE_STATE. Avant Android 10, les identifiants permanents d'appareil (IMEI/MEID, IMSI, SIM et numéro de série de la build) étaient protégés par l'autorisation d'exécution READ_PHONE_STATE. L'autorisation READ_PRIVILEGED_PHONE_STATE n'est accordée qu'aux applications signées avec la clé de plate-forme et aux applications système privilégiées.

Pour en savoir plus sur les nouvelles exigences d'autorisation, consultez les pages Javadoc pour TelephonyManager.java et Build.java.

Cette modification concerne les API suivantes :

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Build#getSerial

Accès pour les applications d'opérateur sans autorisation READ_PRIVILEGED_PHONE_STATE

Les applications d'opérateur préchargées qui ne sont pas éligibles à l'autorisation READ_PRIVILEGED_PHONE_STATE peuvent implémenter l'une des options du tableau ci-dessous.

Option Description Limites
Droits d'accès de l'opérateur UICC La plate-forme Android charge les certificats stockés sur l'UICC et accorde l'autorisation aux applications signées par ces certificats d'effectuer des appels à des méthodes spéciales. Les opérateurs historiques disposent d'une population de cartes SIM importante et établie, qui n'est pas facilement modifiable. De plus, les opérateurs qui ne disposent pas des droits de création de nouvelles cartes SIM (par exemple, les MVNO qui ont des cartes SIM émises par des MNO) ne peuvent pas ajouter ni mettre à jour les certificats sur les cartes SIM.
Ajout d'OEM à la liste d'autorisation Les OEM peuvent utiliser OP_READ_DEVICE_IDENTIFIER pour fournir des identifiants d'appareil aux applications d'opérateur ajoutées à la liste d'autorisation. Cette solution n'est pas évolutive pour tous les opérateurs.
Code d'allocation de type (TAC) Utilisez la méthode getTypeAllocationCode, introduite dans Android 10, pour exposer le TAC qui renvoie les informations sur le fabricant et le modèle. Les informations contenues dans le TAC ne permettent pas d'identifier un appareil spécifique.
MSISDN Les opérateurs peuvent utiliser le numéro de téléphone (MSISDN), disponible sous TelephonyManager avec le groupe d'autorisations PHONE, pour rechercher l'IMEI dans leurs systèmes backend. Cela nécessite un investissement important de la part des opérateurs. Les opérateurs qui mappent leurs clés réseau à l'aide de l'IMSI ont besoin de ressources techniques importantes pour passer au MSISDN.

Toutes les applications d'opérateur peuvent accéder aux identifiants de l'appareil en mettant à jour le fichier CarrierConfig.xml avec le hachage du certificat de signature de l'application d'opérateur. Lorsque l'application d'opérateur appelle une méthode pour lire des informations privilégiées, la plate-forme recherche une correspondance du hachage du certificat de signature de l'application (signature SHA-1 ou SHA-256 du certificat) dans le fichier CarrierConfig.xml. Si une correspondance est trouvée, les informations demandées sont renvoyées. Si aucune correspondance n'est trouvée, une exception de sécurité est renvoyée.

Pour implémenter cette solution, les opérateurs DOIVENT suivre les étapes suivantes :

  1. Mettez à jour CarrierConfig.xml avec le hachage du certificat de signature de l'application de l'opérateur, puis envoyez un correctif.
  2. Demandez aux OEM de mettre à jour leur build avec QPR-1 ou une version ultérieure (recommandé) OU ces correctifs de plate-forme requis et le correctif contenant le fichier CarrierConfig.xml mis à jour de l'étape 1 ci-dessus.

Implémentation

Mettez à jour votre liste d'autorisation des autorisations privilégiées pour accorder l'autorisation READ_PRIVILEGED_PHONE_STATE aux applications privilégiées qui ont besoin d'accéder aux identifiants de l'appareil.

Pour en savoir plus sur l'ajout à la liste d'autorisation, consultez Ajout à la liste d'autorisation des autorisations privilégiées.

Pour appeler les API concernées, une application doit remplir l'une des conditions suivantes :

  • Si l'application est une application privilégiée préchargée, elle doit disposer de l'autorisation READ_PRIVILEGED_PHONE_STATE déclarée dans AndroidManifest.xml. L'application doit également ajouter cette autorisation privilégiée à la liste d'autorisation.
  • Les applications distribuées via Google Play nécessitent des droits d'opérateur. Pour en savoir plus sur l'attribution de droits d'accès à un opérateur, consultez la page Droits d'accès de l'opérateur UICC.
  • Application propriétaire d'un appareil ou d'un profil à laquelle l'autorisation READ_PHONE_STATE a été accordée.

Une application qui ne répond à aucune de ces exigences présente le comportement suivant :

  • Si l'application cible une version antérieure à Q et que l'autorisation READ_PHONE_STATE n'est pas accordée, SecurityException est déclenché. Il s'agit du comportement actuel avant Q, car cette autorisation est requise pour appeler ces API.
  • Si l'application cible une version antérieure à Q et que l'autorisation READ_PHONE_STATE lui est accordée, elle reçoit une valeur nulle pour toutes les API TelephonyManager et Build.UNKNOWN pour la méthode Build#getSerial.
  • Si l'application cible Android 10 ou une version ultérieure et ne répond pas à l'une des nouvelles exigences, elle reçoit une exception SecurityException.

Validation et test

La Compatibility Test Suite (CTS) inclut des tests permettant de vérifier le comportement d'accès aux identifiants d'appareil attendu pour les applications disposant de privilèges d'opérateur, les propriétaires d'appareils et de profils, ainsi que les applications qui ne sont pas censées avoir accès aux identifiants d'appareil.

Les tests CTS suivants sont spécifiques à cette fonctionnalité.

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

Questions fréquentes

Combien d'applications peuvent être ajoutées à la liste d'autorisation dans CarrierConfig.xml pour un couple (CM, MNC) donné ?

Le nombre de hachages de certificat inclus dans le tableau n'est pas limité.

Quels paramètres CarrierConfig de CarrierConfig.xml dois-je utiliser pour qu'une application soit ajoutée à la liste d'autorisation ?

Utilisez l'élément de configuration de premier niveau suivant dans le CarrierConfig.xml spécifique des options AOSP que vous configurez :

<string-array name="carrier_certificate_string_array" num="2">
    <item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/>
    <item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/>
</string-array>

Existe-t-il un modèle CarrierConfig de base que je peux utiliser ?

Utilisez le modèle suivant. Il doit être ajouté au composant concerné.

<?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 carte SIM de l'opérateur doit-elle se trouver dans l'appareil pour accéder aux identifiants de l'appareil ?

Le CarrierConfig.xml utilisé est déterminé en fonction de la carte SIM actuellement insérée. Cela signifie que si l'application de l'opérateur X tente d'obtenir des droits d'accès alors que la carte SIM de l'opérateur Y est insérée, l'appareil ne trouvera pas de correspondance pour le hachage et renverra une exception de sécurité.

Sur les appareils multi-SIM, l'opérateur 1 ne dispose de droits d'accès que pour la SIM 1, et inversement.

Comment les opérateurs convertissent-ils le certificat de signature d'une application en hachage ?

Pour convertir les certificats de signature en hachage avant de les ajouter à CarrierConfig.xml, procédez comme suit :

  1. Convertissez la signature du certificat de signature en tableau d'octets à l'aide de toByteArray.
  2. Utilisez MessageDigest pour convertir le tableau d'octets en hachage de type byte[].
  3. Convertissez le hachage de byte[] en chaîne hexadécimale. Pour obtenir un exemple, consultez 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 est un tableau de taille 2 avec une valeur 12345 et 54321, ajoutez les éléments suivants au fichier de configuration de l'opérateur.

    <string-array name="carrier_certificate_string_array" num="2">
        <item value="12345"/>
        <item value="54321"/>
    </string-array>