O Android 10 altera as permissões para identificadores de dispositivo para que todos os identificadores de dispositivo agora sejam protegidos pela permissão READ_PRIVILEGED_PHONE_STATE
. Antes do Android 10, os identificadores de dispositivo persistentes (IMEI / MEID, IMSI, SIM e série de compilação) eram protegidos pela permissão de tempo de execução READ_PHONE_STATE
. A permissão READ_PRIVILEGED_PHONE_STATE
é concedida apenas a aplicativos assinados com a chave de plataforma e aplicativos de sistema com privilégios.
Mais informações sobre os novos requisitos de permissão podem ser encontradas nas páginas Javadoc para TelephonyManager.java e Build.java .
Essa mudança afeta as seguintes APIs:
- TelephonyManager # getDeviceId
- TelephonyManager # getImei
- TelephonyManager # getMeid
- TelephonyManager # getSimSerialNumber
- TelephonyManager # getSubscriberId
- Build # getSerial
Acesso para aplicativos de operadora sem permissão READ_PRIVILEGED_PHONE_STATE
Aplicativos de operadora READ_PRIVILEGED_PHONE_STATE
carregados que não se qualificam para a permissão READ_PRIVILEGED_PHONE_STATE
podem implementar uma das opções na tabela abaixo.
Opção | Desciption | Limitações |
---|---|---|
Privilégios de operadora UICC | A plataforma Android carrega certificados armazenados no UICC e concede permissão aos aplicativos assinados por esses certificados para fazer chamadas para métodos especiais. | As operadoras legadas têm uma grande população de SIMs estabelecida, que não é facilmente atualizável. Além disso, as operadoras que não têm direitos de autoria para novos SIMs (por exemplo, MVNOs que têm SIMs emitidos de MNOs) não podem adicionar ou atualizar certificados nos SIMs. |
Lista de permissões de OEM | Os OEMs podem usar OP_READ_DEVICE_IDENTIFIER para fornecer identificadores de dispositivo para aplicativos de operadora permitidos. | Esta solução não é escalonável para todas as operadoras. |
Código de alocação de tipo (TAC) | Use o método getTypeAllocationCode , introduzido no Android 10, para expor o TAC que retorna as informações do fabricante e do modelo. | As informações no TAC são inadequadas para identificar um dispositivo específico. |
MSISDN | As operadoras podem usar o número de telefone (MSISDN), disponível em TelephonyManager com o grupo de permissão PHONE , para pesquisar o IMEI em seus sistemas back-end. | Isso requer um investimento significativo para as operadoras. Operadoras que mapeiam suas chaves de rede usando IMSI requerem recursos técnicos significativos para mudar para MSISDN . |
Todos os aplicativos de operadora podem acessar identificadores de dispositivo atualizando o arquivo CarrierConfig.xml
com o hash de certificado de assinatura do aplicativo de operadora. Quando o aplicativo da operadora chama um método para ler informações privilegiadas, a plataforma procura uma correspondência do hash do certificado de assinatura do aplicativo (assinatura SHA-1 ou SHA-256 do certificado) no arquivo CarrierConfig.xml
. Se uma correspondência for encontrada, as informações solicitadas são retornadas. Se nenhuma correspondência for encontrada, uma exceção de segurança será retornada.
Para implementar essa solução, as operadoras DEVEM seguir estas etapas:
- Atualize
CarrierConfig.xml
com o hash do certificado de assinatura do aplicativo da operadora e envie um patch . - Solicite aos OEMs que atualizem seu build com QPR1 + (recomendado) OU estes patches de plataforma necessários e o patch contendo o arquivo
CarrierConfig.xml
atualizado da etapa 1 acima.
Implementação
Atualize sua lista de permissões de permissão privilegiada para conceder a permissão READ_PRIVILEGED_PHONE_STATE
aos aplicativos privilegiados que requerem acesso a identificadores de dispositivo.
Para saber mais sobre a lista de permissões, consulte Lista de permissões com privilégios .
Para invocar as APIs afetadas, um aplicativo deve atender a um dos seguintes requisitos:
- Se o aplicativo for um aplicativo com privilégios pré-carregado, ele precisará da permissão
READ_PRIVILEGED_PHONE_STATE
declarada em AndroidManifest.xml. O aplicativo também precisa colocar essa permissão privilegiada na lista de permissões. - Os aplicativos fornecidos por meio do Google Play precisam de privilégios de operadora. Saiba mais sobre como conceder privilégios de operadora na página UICC Carrier Privileges .
- Um aplicativo de proprietário de dispositivo ou perfil que recebeu a permissão
READ_PHONE_STATE
.
Um aplicativo que não atende a nenhum desses requisitos tem o seguinte comportamento:
- Se o aplicativo for pré-Q e não tiver a permissão
READ_PHONE_STATE
concedida,SecurityException
é acionado. este é o comportamento pré-Q atual, pois essa permissão é necessária para invocar essas APIs. - Se o aplicativo for pré-Q e tiver a permissão
READ_PHONE_STATE
concedida, ele receberá um valor nulo para todas as APIs TelephonyManager eBuild.UNKNOWN
para o métodoBuild#getSerial
. - Se o aplicativo for direcionado ao Android 10 ou superior e não atender a nenhum dos novos requisitos, ele receberá uma SecurityException.
Validação e teste
O Compatibility Test Suite (CTS) inclui testes para verificar o comportamento de acesso do identificador de dispositivo esperado para aplicativos com privilégios de operadora, proprietários de dispositivo e perfil e aqueles aplicativos que não devem ter acesso a identificadores de dispositivo.
Os seguintes testes CTS são específicos para este recurso.
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
FAQs
Quantos aplicativos podem ser CarrierConfig.xml
na lista de permissões em CarrierConfig.xml
para um determinado (MCC, MNC)?
Não há limite para o número de hashes de certificado incluídos na matriz.
Quais parâmetros CarrierConfig em CarrierConfig.xml
preciso usar para que um aplicativo seja colocado na lista de permissões?
Use o seguinte item de configuração de nível superior no CarrierConfig.xml
específico das opções AOSP que você está configurando:
<string-array name="carrier_certificate_string_array" num="2"> <item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/> <item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/> </string-array>
Existe um modelo base CarrierConfig que posso usar?
Use o seguinte modelo. Isso deve ser adicionado ao ativo relevante .
<?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>
O SIM da operadora precisa estar no dispositivo para acessar os identificadores do dispositivo?
O CarrierConfig.xml
usado é determinado com base no SIM inserido no momento. Isso significa que se o aplicativo da operadora X tentar obter privilégios de acesso enquanto o SIM da operadora Y estiver inserido, o dispositivo não encontrará uma correspondência para o hash e retornará uma exceção de segurança.
Em dispositivos multi-SIM, a operadora # 1 só tem privilégios de acesso para o SIM # 1 e vice-versa.
Como as operadoras convertem o certificado de assinatura de um aplicativo em hash?
Para converter certificados de assinatura em hash antes de adicioná-los a CarrierConfig.xml
, faça o seguinte:
- Converta a assinatura do certificado de assinatura em uma matriz de bytes usando
toByteArray
. - Use
MessageDigest
para converter a matriz de bytes em um hash no tipo byte []. Converta o hash do byte [] em um formato de string hexadecimal. Para obter um exemplo, 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())); }
Se
certHashes
for uma matriz de tamanho2
com um valor de12345
e54321
, adicione o seguinte ao arquivo de configuração da operadora.<string-array name="carrier_certificate_string_array" num="2"> <item value="12345"/> <item value="54321"/> </string-array>