Identificadores de dispositivo

O Android 10 muda as permissões para identificadores de dispositivo. Dessa forma, todos eles são protegidos por a permissão READ_PRIVILEGED_PHONE_STATE. Antes de Android 10, identificadores de dispositivo persistentes (IMEI/MEID, IMSI, chip e número de série da versão) estavam protegidos Permissão de execução READ_PHONE_STATE. A permissão READ_PRIVILEGED_PHONE_STATE só é concedido a apps assinados com a chave de plataforma e apps de sistema privilegiados.

Mais informações sobre os novos requisitos de permissão podem ser encontradas na Páginas Javadoc para TelephonyManager.java e Build.java.

Essa mudança afeta as seguintes APIs:

  • Gerente de telefonia#getDeviceId
  • Gerente de telefonia#getImei
  • Gerente de telefonia#getMeid
  • Gerente de Telefonia#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Build#getSerial

Acesso a apps de operadoras sem a permissão READ_PRIVILEGED_PHONE_STATE

Apps de operadoras pré-carregados que não estão qualificados para o READ_PRIVILEGED_PHONE_STATE permissão pode 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 aplicativos assinados por esses certificados para fazer chamadas para métodos. As operadoras antigas têm um número grande e estabelecido de chips, que não é facilmente atualizáveis. Além disso, as operadoras que não têm direitos de criação de novos Chips (por exemplo, OMVs que têm chips emitidos por MNOs) não podem adicionar nem e atualizar os certificados nos chips.
Lista de permissões do OEM OEMs podem usar OP_READ_DEVICE_IDENTIFIER para fornecer identificadores aos apps de operadoras permitidos. Essa solução não é escalonável para todas as operadoras.
Tipo de código de alocação (TAC) Use o getTypeAllocationCode , introduzido na Android 10, para expor o TAC que retorna o fabricante e o modelo informações. 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 a permissão PHONE para procurar o IMEI nos sistemas de back-end. Para isso, as transportadoras fazem um investimento significativo. Operadoras que mapeiam as chaves de rede com IMSI requerem recursos técnicos para mudar para o MSISDN.

Todos os apps de operadoras podem acessar identificadores de dispositivos com a atualização o arquivo CarrierConfig.xml com o hash de certificado de assinatura de app da operadora. Quando o app da operadora chama um método para ler dados privilegiados a plataforma procura uma correspondência do certificado de assinatura do app (assinatura SHA-1 ou SHA-256 do certificado) no arquivo CarrierConfig.xml. Se uma correspondência for encontrada, o valor informações sejam retornadas. Se nenhuma correspondência for encontrada, uma exceção de segurança será retornados.

Para implementar essa solução, as operadoras PRECISAM seguir estas etapas:

  1. Atualizar CarrierConfig.xml pelo hash do certificado de assinatura do app da operadora e enviar um patch.
  2. Solicite que os OEMs atualizem o build com o QPR1+ (recomendado) OU estes: patches de plataforma necessários e o patch que contém atualizou o arquivo CarrierConfig.xml da etapa 1 acima.

Implementação

Atualize sua lista de permissões de permissões privilegiadas para conceder o Permissão READ_PRIVILEGED_PHONE_STATE para os usuários com privilégios e apps que exigem acesso a identificadores de dispositivo.

Para saber mais sobre a lista de permissões, consulte Acesso privilegiado Lista de permissões de permissões.

Para invocar as APIs afetadas, um app precisa atender a um dos seguintes requisitos requisitos:

  • Se o aplicativo for um aplicativo privilegiado pré-carregado, ele precisa da READ_PRIVILEGED_PHONE_STATE permissão declarada em AndroidManifest.xml O app também precisa autorizar essa permissão privilegiada.
  • Os apps fornecidos pelo Google Play precisam de privilégios de operadora. Saiba mais sobre como conceder privilégios de operadora na Operadora do UICC Privilégios.
  • Um app proprietário de dispositivo ou perfil com o READ_PHONE_STATE.

Um app que não atende a nenhum desses requisitos tem os seguintes comportamento:

  • Se o app for destinado antes do trimestre e não tiver a READ_PHONE_STATE permissão concedida, SecurityException é acionada. este é o comportamento anterior ao Q, porque a permissão para invocar essas APIs.
  • Se o app for destinado antes do trimestre e tiver READ_PHONE_STATE concedida, ele recebe um valor nulo para todas as APIs TelephonyManager e Build.UNKNOWN para o método Build#getSerial.
  • Se o app for direcionado ao Android 10 ou mais recente e não atende a nenhum dos novos ele recebe uma SecurityException.

Validação e teste

A página de API O conjunto de testes (CTS) inclui testes para verificar o identificador do dispositivo esperado comportamento de acesso para apps com privilégios de operadora, dispositivos e proprietários de perfil e os apps que provavelmente não terão acesso ao dispositivo identificadores.

Os testes de CTS a seguir são específicos para esse 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

Perguntas frequentes

Quantos apps podem ser incluídos na lista de permissões do CarrierConfig.xml para um determinado (MCC, MNC)?

Não há limite para o número de hashes de certificados incluídos na matriz.

Quais parâmetros de CarrierConfig em CarrierConfig.xml preciso usar para que um app seja incluído na lista de permissões?

Use o seguinte item de configuração de nível superior na API CarrierConfig.xml nas 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 CarrierConfig que eu possa usar?

Use o modelo a seguir. Ela deve ser adicionada 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 chip da operadora Y for inserido, o dispositivo não encontrará uma correspondência para o hash e retorna 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 hash?

Converter certificados de assinatura em um hash antes de adicioná-los ao CarrierConfig.xml, faça o seguinte:

  1. Converta a assinatura do certificado de assinatura em uma matriz de bytes usando toByteArray.
  2. Usar MessageDigest para converter a matriz de bytes em um hash byte[].
  3. Converta o hash de byte[] em um formato de string hexadecimal. Por 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()));
    }
    
  4. Se certHashes for uma matriz de tamanho 2 com um valor de 12345 e 54321, 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>