O Android 10 muda as permissões para
identificadores de dispositivo. Agora, todos eles são protegidos pela
permissão READ_PRIVILEGED_PHONE_STATE. Antes do Android 10, os identificadores de dispositivo persistentes (IMEI/MEID, IMSI, SIM e número de série da versão) eram protegidos pela permissão de tempo de execução READ_PHONE_STATE.
A permissão READ_PRIVILEGED_PHONE_STATE só é
concedida a apps assinados com a chave da plataforma e apps privilegiados do sistema.
Mais informações sobre os novos requisitos de permissão podem ser encontradas nas páginas do 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 apps de operadora sem a permissão READ_PRIVILEGED_PHONE_STATE
Os apps de operadora pré-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 | Descrição | Limitações |
|---|---|---|
| Privilégios da operadora UICC | A plataforma Android carrega certificados armazenados no UICC e concede permissão a apps assinados por esses certificados para fazer chamadas a métodos especiais. | As operadoras legadas têm uma população grande e estabelecida de SIMs, que não é facilmente atualizável. Além disso, as operadoras que não têm direitos de criação de novos chips (por exemplo, MVNOs que têm chips emitidos por MNOs) não podem adicionar ou atualizar certificados nos chips. |
| Lista de permissões de OEM | Os OEMs podem usar o OP_READ_DEVICE_IDENTIFIER para fornecer identificadores de dispositivo a apps de operadoras na lista de permissões. |
Essa 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ões PHONE, para pesquisar o IMEI nos sistemas de back-end. |
Isso exige um investimento significativo das operadoras. As operadoras que mapeiam as chaves de rede usando o IMSI precisam de muitos recursos técnicos para mudar para o MSISDN. |
Todos os apps de operadora podem acessar identificadores de dispositivo atualizando o arquivo CarrierConfig.xml com o hash do certificado de assinatura do app de operadora. Quando o app de operadora chama um método para ler informações privilegiadas, a plataforma procura uma correspondência do hash do certificado de assinatura do app (assinatura SHA-1 ou SHA-256 do certificado) no arquivo CarrierConfig.xml. Se uma correspondência for encontrada, as informações solicitadas serão retornadas. Se nenhuma correspondência for encontrada, uma exceção de segurança será retornada.
Para implementar essa solução, as transportadoras precisam seguir estas etapas:
- Atualize
CarrierConfig.xmlcom o hash do certificado de assinatura do app da operadora e envie um patch. - Peça aos OEMs para atualizar o build com QPR1+ (recomendado) OU estes
patches de plataforma obrigatórios e o patch que contém o
arquivo
CarrierConfig.xmlatualizado da etapa 1 acima.
Implementação
Atualize sua lista de permissões privilegiadas para conceder a permissão
READ_PRIVILEGED_PHONE_STATE aos apps privilegiados
que precisam de acesso a identificadores de dispositivos.
Para saber mais sobre a lista de permissões, consulte Lista de permissões de permissões privilegiadas.
Para invocar as APIs afetadas, um app precisa atender a um dos seguintes requisitos:
- Se o app for um app privilegiado pré-carregado, ele precisará da
permissão
READ_PRIVILEGED_PHONE_STATEdeclarada em AndroidManifest.xml. O app também precisa permitir essa permissão privilegiada na lista de permissões. - Os apps entregues pelo Google Play precisam de privilégios da operadora. Saiba mais sobre como conceder privilégios de operadora na página Privilégios da operadora UICC.
- Um app de proprietário do dispositivo ou do perfil que recebeu a permissão
READ_PHONE_STATE.
Um app que não atende a nenhum desses requisitos tem o seguinte comportamento:
- Se o app for destinado a versões anteriores ao Android Q e não tiver a permissão
READ_PHONE_STATEconcedida,SecurityExceptionserá acionado. Esse é o comportamento atual antes do Android Q, já que essa permissão é necessária para invocar essas APIs. - Se o app segmentar versões anteriores ao Android Q e tiver a permissão
READ_PHONE_STATEconcedida, ele vai receber um valor nulo para todas as APIs TelephonyManager eBuild.UNKNOWNpara o métodoBuild#getSerial. - Se o app for destinado ao Android 10 ou versões mais recentes e não atender a nenhum dos novos requisitos, ele vai receber uma SecurityException.
Validação e teste
O Compatibility Test Suite (CTS) inclui testes para verificar o comportamento esperado de acesso ao identificador de dispositivo para apps com privilégios de operadora, proprietários de dispositivos e perfis e apps que não devem ter acesso a identificadores de dispositivo.
Os seguintes testes do CTS são específicos desse recurso.
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
Perguntas frequentes
Quantos apps podem ser incluídos 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 app seja adicionado à lista de permissões?
Use o seguinte item de configuração de nível superior no CarrierConfig.xml específico das opções do 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 básico de CarrierConfig que eu possa usar?
Use o modelo a seguir. Isso precisa ser adicionado ao recurso 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 chip da operadora precisa estar no dispositivo para acessar os identificadores?
O CarrierConfig.xml usado é determinado com base no
chip inserido no momento. Isso significa que, se o app da operadora X tentar
receber privilégios de acesso enquanto o SIM da operadora Y estiver inserido, o dispositivo não vai encontrar
uma correspondência para o hash e vai retornar uma exceção de segurança.
Em dispositivos com vários chips, a operadora 1 só tem privilégios de acesso para o chip 1 e vice-versa.
Como as operadoras convertem o certificado de assinatura de um app em um hash?
Para converter certificados de assinatura em um hash antes de adicioná-los ao
CarrierConfig.xml, faça o seguinte:
- Converta a assinatura do certificado de assinatura em uma matriz de bytes usando
toByteArray. - Use
MessageDigestpara converter a matriz de bytes em um hash do tipo byte[]. -
Converta o hash de byte[] para um formato de string hexadecimal. Para conferir 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
certHashesfor uma matriz de tamanho2com um valor de12345e54321, 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>