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 persistenti del dispositivo (IMEI/MEID, IMSI, SIM e numero di serie della build) erano protetti dall'autorizzazione di runtime READ_PHONE_STATE
. L'autorizzazione READ_PRIVILEGED_PHONE_STATE
è concessa solo alle app firmate con la chiave della piattaforma e alle app di sistema privilegiate.
Ulteriori informazioni sui nuovi requisiti di autorizzazione sono disponibili nelle pagine Javadoc per TelephonyManager.java e Build.java .
Questa modifica influisce sulle seguenti API:
- Gestoretelefonia#getDeviceId
- Gestore Telefonia#getImei
- Responsabile della telefonia#getMeid
- Gestore Telefonia#getSimSerialNumber
- Gestoretelefonia#getSubscriberId
- Costruisci#getSerial
Accesso per le app dell'operatore senza l'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 nella tabella seguente.
Opzione | Descrizione | Limitazioni |
---|---|---|
Privilegi del vettore UICC | La piattaforma Android carica i certificati archiviati nell'UICC e concede l'autorizzazione alle app firmate da questi certificati per effettuare chiamate a metodi speciali. | Gli operatori legacy hanno una popolazione SIM ampia e consolidata, che non è facilmente aggiornabile. Inoltre, gli operatori che non dispongono dei diritti di creazione sulle nuove SIM (ad esempio, gli MVNO che hanno SIM emesse da MNO) non possono aggiungere o aggiornare i certificati sulle SIM. |
Inserimento nella lista consentita OEM | Gli OEM possono utilizzare OP_READ_DEVICE_IDENTIFIER per fornire identificatori del dispositivo alle app degli operatori consentiti. | Questa soluzione non è scalabile per tutti gli operatori. |
Codice di assegnazione 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 contenute nel TAC sono inadeguate 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 sui loro sistemi backend. | Ciò richiede investimenti significativi per i vettori. Gli operatori che mappano le proprie chiavi di rete utilizzando IMSI richiedono notevoli risorse tecniche per passare a 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 le 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, i corrieri DEVONO seguire questi passaggi:
- Aggiorna
CarrierConfig.xml
con l'hash del certificato di firma dell'app dell'operatore e invia una patch . - Richiedere agli OEM di aggiornare la propria build con QPR1+ (consigliato) OPPURE queste patch della piattaforma richieste e la patch contenente il file
CarrierConfig.xml
aggiornato dal passaggio 1 sopra.
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 ulteriori informazioni sull'inserimento nella lista consentita, fare riferimento a Inserimento nella lista consentita con autorizzazioni privilegiate .
Per richiamare le API interessate, un'app deve soddisfare uno dei seguenti requisiti:
- Se l'app è un'applicazione privilegiata precaricata, è necessaria l'autorizzazione
READ_PRIVILEGED_PHONE_STATE
dichiarata in AndroidManifest.xml. L'app deve inoltre consentire questa autorizzazione privilegiata. - Le app distribuite tramite Google Play necessitano dei privilegi dell'operatore. Scopri di più sulla concessione dei privilegi dell'operatore nella pagina Privilegi dell'operatore UICC .
- Un'app del proprietario 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 è destinata alla fase pre-Q e non dispone dell'autorizzazione
READ_PHONE_STATE
concessa, viene attivataSecurityException
. questo è l'attuale comportamento pre-Q poiché è necessaria questa autorizzazione per richiamare queste API. - Se l'app ha come destinazione pre-Q e dispone dell'autorizzazione
READ_PHONE_STATE
concessa, riceve un valore null per tutte le API TelephonyManager eBuild.UNKNOWN
per il metodoBuild#getSerial
. - Se l'app è destinata ad Android 10 o versioni successive e non soddisfa nessuno dei nuovi requisiti, riceve un'eccezione SecurityException.
Validazione e test
La Compatibility Test Suite (CTS) include test per verificare il comportamento previsto di accesso agli identificatori del dispositivo per le app con privilegi dell'operatore, proprietari di dispositivi e profili e quelle app che si prevede non abbiano accesso agli identificatori del dispositivo.
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 dato (MCC, MNC)?
Non esiste alcun limite al numero di hash del certificato inclusi nell'array.
Quali parametri CarrierConfig in CarrierConfig.xml
devo utilizzare affinché un'app venga inserita nella lista consentita?
Utilizza il seguente elemento di configurazione di livello superiore all'interno del CarrierConfig.xml
specifico dalle 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 dovrebbe essere aggiunto alla risorsa 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 restituirà 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 come segue:
- Convertire la firma del certificato di firma in un array di byte utilizzando
toByteArray
. - Utilizzare
MessageDigest
per convertire l'array di byte in un hash di tipo byte[]. Converti l'hash da byte[] in un formato stringa esadecimale. Per un esempio, vedere
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 dimensione2
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>