Android 10 modifica le autorizzazioni per gli identificatori dei dispositivi in modo che tutti gli identificatori dei dispositivi siano ora protetti dall'autorizzazione READ_PRIVILEGED_PHONE_STATE
. Prima di Android 10, gli identificatori del dispositivo persistenti (IMEI/MEID, IMSI, SIM e numero di serie nella build) erano protetti dall'autorizzazione 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.
Puoi trovare maggiori informazioni sui nuovi requisiti di autorizzazione nelle pagine Javadoc di 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 autorizzazione READ_PRIVILEGED_PHONE_STATE
Le app dell'operatore precaricate che non sono idonee per l'autorizzazione READ_PRIVILEGED_PHONE_STATE
possono implementare una delle opzioni riportate nella tabella seguente.
Opzione | Descrizione | Limitazioni |
---|---|---|
Privilegi dell'operatore UICC | La piattaforma Android carica i certificati archiviati nella UICC e concede alle app firmate da questi certificati l'autorizzazione per effettuare chiamate a metodi speciali. | Gli operatori legacy hanno una vasta popolazione di SIM consolidate, che non è facilmente aggiornabile. Inoltre, gli operatori che non dispongono dei diritti di autore per le 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 dell'operatore inserite nella lista consentita. |
Questa soluzione non è scalabile per tutti gli operatori. |
Codice di allocazione del tipo (TAC) | Utilizza il metodo
getTypeAllocationCode
introdotto in Android 10 per esporre il TAC che restituisce le informazioni sul produttore e sul modello. |
Le informazioni nel TAC non sono adeguate per identificare un dispositivo specifico. |
MSISDN | Gli operatori possono utilizzare il numero di telefono (MSISDN), disponibile in
TelephonyManager con il gruppo di autorizzazione PHONE , per cercare l'IMEI nei propri sistemi di backend. |
Ciò richiede investimenti significativi per i vettori. 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. 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.xml
con l'hash del certificato di firma dell'app dell'operatore e invia una patch. - Chiedi agli OEM di aggiornare la build con QPR1 o versioni successive (opzione consigliata) OPPURE con queste
patch della piattaforma richieste e la patch contenente
il file
CarrierConfig.xml
aggiornato 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 Lista consentita per le autorizzazioni con privilegi.
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_STATE
dichiarata in AndroidManifest.xml. L'app deve anche inserire nella lista consentita questa autorizzazione privilegiata. - Le app distribuite tramite Google Play richiedono i privilegi dell'operatore. Scopri di più sulla concessione dei privilegi dell'operatore nella pagina Privilegi dell'operatore UICC.
- Un'app di proprietà del dispositivo o del profilo a cui è stata concessa l'autorizzazione
READ_PHONE_STATE
.
Un'app che non soddisfa nessuno di questi requisiti presenta il seguente comportamento:
- Se l'app ha come target versioni precedenti a Q e non ha l'autorizzazione
READ_PHONE_STATE
concessa, viene attivatoSecurityException
. Questo è il comportamento attuale precedente a Q, poiché questa autorizzazione è necessaria per richiamare queste API. - Se l'app ha come target le versioni precedenti a Q e ha l'autorizzazione
READ_PHONE_STATE
concessa, riceve un valore nullo per tutte le API TelephonyManager eBuild.UNKNOWN
per il metodoBuild#getSerial
. - Se l'app ha come target Android 10 o versioni successive e non soddisfa nessuno dei nuovi requisiti, riceve una SecurityException.
Convalida e test
La Compatibility Test Suite (CTS) include test per verificare il comportamento di accesso agli identificatori dei dispositivi previsto per le app con privilegi dell'operatore, i proprietari di dispositivi e di profili e le app che non dovrebbero 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.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
Domande frequenti
Quante app possono essere inserite nella lista consentita in CarrierConfig.xml
per un determinato (Centro clienti, proprietà multicanale)?
Non è previsto 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 del 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 valore 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 valore CarrierConfig.xml
utilizzato viene determinato in base alla SIM attualmente inserita. Ciò significa che se l'app dell'operatore X tenta di ottenere i privilegi di accesso quando è inserita la SIM dell'operatore Y, il dispositivo non troverà una corrispondenza per l'hash e restituirà un'eccezione di sicurezza.
Sui dispositivi con più SIM, l'operatore 1 ha i privilegi di accesso solo per la SIM 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
:
- Converti la firma del certificato di firma in un array di byte utilizzando
toByteArray
. - Utilizza
MessageDigest
per convertire l'array di byte in un hash di tipo byte[]. -
Converte l'hash da byte[] in un formato di stringa esadecimale. Per un esempio, consulta
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 dimensioni2
con un valore di12345
e54321
, 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>