Android 10 modifica le autorizzazioni per gli identificatori del dispositivo in modo che tutti gli identificatori del dispositivo siano ora protetti dall'autorizzazione READ_PRIVILEGED_PHONE_STATE. Prima di
Android 10, gli identificatori dispositivo permanenti
(IMEI/MEID, IMSI, SIM e numero di serie della build) erano protetti dal
permesso di runtime READ_PHONE_STATE.
L'autorizzazione READ_PRIVILEGED_PHONE_STATE viene concessa solo alle app firmate con la chiave della piattaforma e alle app di sistema privilegiate.
Per ulteriori informazioni sui nuovi requisiti di autorizzazione, consulta le pagine Javadoc per TelephonyManager.java e Build.java.
Questa modifica interessa le seguenti API:
- TelephonyManager#getDeviceId
- TelephonyManager#getImei
- TelephonyManager#getMeid
- TelephonyManager#getSimSerialNumber
- TelephonyManager#getSubscriberId
- Build#getSerial
Accesso per le app dell'operatore senza l'autorizzazione READ_PRIVILEGED_PHONE_STATE
Le app dell'operatore precaricate che non soddisfano i requisiti per l'autorizzazione
READ_PRIVILEGED_PHONE_STATE
possono implementare una delle opzioni nella tabella seguente.
| Opzione | Descrizione | Limitazioni |
|---|---|---|
| Privilegi dell'operatore UICC | La piattaforma Android carica i certificati memorizzati sulla UICC e concede l'autorizzazione alle app firmate da questi certificati per effettuare chiamate a metodi speciali. | Gli operatori legacy hanno una popolazione di SIM ampia e consolidata, che non è facilmente aggiornabile. Inoltre, gli operatori che non dispongono dei diritti di creazione di nuove SIM (ad esempio, gli MVNO che hanno SIM emesse da MNO) non possono aggiungere o aggiornare i certificati sulle SIM. |
| Lista consentita OEM | Gli OEM possono utilizzare OP_READ_DEVICE_IDENTIFIER per fornire identificatori
di dispositivi alle app operatore consentite. |
Questa soluzione non è scalabile per tutti i corrieri. |
| Codice di allocazione del tipo (TAC) | Utilizza il metodo
getTypeAllocationCode, introdotto in
Android 10, per esporre il TAC che restituisce le informazioni
su produttore e modello. |
Le informazioni nel TAC non sono sufficienti per identificare un dispositivo specifico. |
| MSISDN | Gli operatori possono utilizzare il numero di telefono (MSISDN), disponibile in
TelephonyManager con il gruppo di autorizzazioni PHONE, per cercare l'IMEI nei loro sistemi di backend. |
Ciò richiede investimenti significativi per gli operatori. Gli operatori che mappano le chiavi di rete utilizzando l'IMSI richiedono risorse tecniche significative per passare all'MSISDN. |
Tutte le app dell'operatore possono accedere agli identificatori del dispositivo aggiornando
il file CarrierConfig.xml con l'hash del certificato di firma dell'app dell'operatore. Quando l'app dell'operatore chiama un metodo per leggere informazioni privilegiate, la piattaforma cerca una corrispondenza dell'hash del certificato di firma dell'app (firma SHA-1 o SHA-256 del certificato) nel file CarrierConfig.xml. Se viene trovata una corrispondenza, vengono restituite le informazioni richieste. Se non viene trovata alcuna corrispondenza, viene restituita un'eccezione di sicurezza.
Per implementare questa soluzione, gli operatori DEVONO seguire questi passaggi:
- Aggiorna
CarrierConfig.xmlcon l'hash del certificato di firma dell'app dell'operatore e invia una patch. - Chiedi agli OEM di aggiornare la build con QPR1+ (consigliato) OPPURE con queste
patch della piattaforma richieste e con la patch contenente
il file
CarrierConfig.xmlaggiornato del passaggio 1 precedente.
Implementazione
Aggiorna la lista consentita delle autorizzazioni privilegiate per concedere l'autorizzazione
READ_PRIVILEGED_PHONE_STATE alle app privilegiate
che richiedono l'accesso agli identificatori del dispositivo.
Per scoprire di più sulle liste consentite, consulta Liste consentite per le autorizzazioni privilegiate.
Per richiamare le API interessate, un'app deve soddisfare uno dei seguenti requisiti:
- Se l'app è un'app privilegiata precaricata, ha bisogno dell'autorizzazione
READ_PRIVILEGED_PHONE_STATEdichiarata in AndroidManifest.xml. L'app deve anche inserire questa autorizzazione privilegiata nella lista consentita. - Le app distribuite tramite Google Play richiedono privilegi dell'operatore. Scopri di più sulla concessione dei privilegi dell'operatore nella pagina Privilegi dell'operatore UICC.
- Un'app proprietario del dispositivo o del profilo a cui è stata concessa l'autorizzazione
READ_PHONE_STATE.
Un'app che non soddisfa nessuno di questi requisiti ha il seguente comportamento:
- Se l'app ha come target versioni precedenti ad Android Q e non dispone dell'autorizzazione
READ_PHONE_STATEconcessa,SecurityExceptionviene attivato. Questo è il comportamento attuale delle versioni precedenti ad Android Q, in quanto questa autorizzazione è necessaria per richiamare queste API. - Se l'app ha come target versioni precedenti di Android Q e dispone dell'autorizzazione
READ_PHONE_STATE, riceve un valore nullo per tutte le API TelephonyManager eBuild.UNKNOWNper il metodoBuild#getSerial. - Se l'app ha come target Android 10 o versioni successive e non soddisfa uno dei nuovi requisiti, riceve un'eccezione SecurityException.
Convalida e test
La Compatibility Test Suite (CTS) include test per verificare il comportamento di accesso previsto per gli identificatori dei dispositivi per le app con privilegi dell'operatore, i proprietari di dispositivi e profili e le app che non devono avere accesso agli identificatori dei dispositivi.
I seguenti test CTS sono specifici per questa funzionalità.
cts-tradefed run cts -m CtsCarrierApiTestCases -t android.carrierapi.cts.CarrierApiTestcts-tradefed run cts -m CtsTelephonyTestCases -t android.telephony.cts.TelephonyManagerTestcts-tradefed run cts -m CtsTelephony3TestCasescts-tradefed run cts -m CtsPermissionTestCases -t android.permission.cts.TelephonyManagerPermissionTestcts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCanGetDeviceIdentifierscts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCanGetDeviceIdentifierscts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCannotGetDeviceIdentifiersWithoutPermissioncts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission
Domande frequenti
Quante app possono essere inserite nella lista consentita in CarrierConfig.xml per un determinato (MCC, MNC)?
Non esiste alcun limite al numero di hash dei certificati inclusi nell'array.
Quali parametri CarrierConfig in CarrierConfig.xml devo utilizzare per inserire un'app nella lista consentita?
Utilizza il seguente elemento di configurazione di primo livello all'interno di CarrierConfig.xml specifico delle opzioni AOSP che stai configurando:
<string-array name="carrier_certificate_string_array" num="2">
<item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/>
<item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/>
</string-array>Esiste un modello CarrierConfig di base che posso utilizzare?
Utilizza il seguente modello. Questo deve essere aggiunto all' asset pertinente.
<?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 dell'operatore deve essere inserita nel dispositivo per accedere agli identificatori del dispositivo?
Il CarrierConfig.xml utilizzato viene determinato in base alla
SIM attualmente inserita. Ciò significa che se l'app dell'operatore X tenta di
ottenere privilegi di accesso mentre è inserita la SIM dell'operatore Y, il dispositivo non troverà
una corrispondenza per l'hash e restituisce un'eccezione di sicurezza.
Sui dispositivi multi-SIM, l'operatore n. 1 ha privilegi di accesso solo per la SIM n. 1 e viceversa.
In che modo gli operatori convertono il certificato di firma di un'app in un hash?
Per convertire i certificati di firma in un hash prima di aggiungerli a
CarrierConfig.xml, procedi nel seguente modo:
- Converti la firma del certificato di firma in un array di byte utilizzando
toByteArray. - Utilizza
MessageDigestper convertire l'array di byte in un hash di tipo byte[]. -
Converti l'hash da byte[] in una stringa esadecimale. Per un esempio, vedi
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())); } Se
certHashesè un array di dimensioni2con un valore di12345e54321, aggiungi quanto segue al file di configurazione dell'operatore.<string-array name="carrier_certificate_string_array" num="2"> <item value="12345"/> <item value="54321"/> </string-array>