Identificadores de dispositivos

O Android 10 altera as permissões para identificadores de dispositivos para que todos os identificadores de dispositivos agora sejam protegidos pela permissão READ_PRIVILEGED_PHONE_STATE . Antes do Android 10, identificadores de dispositivos persistentes (IMEI/MEID, IMSI, SIM e serial de compilação) eram protegidos pela permissão de tempo de execução READ_PHONE_STATE . A permissão READ_PRIVILEGED_PHONE_STATE só é concedida a aplicativos assinados com a chave da plataforma e aplicativos de sistema privilegiados.

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

Essa alteração afeta as seguintes APIs:

  • TelephonyManager#getDeviceId
  • Gerenciador de telefonia#getImei
  • Gerenciador de telefonia#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Construir#getSerial

Acesso para aplicativos de operadora sem permissão READ_PRIVILEGED_PHONE_STATE

Os aplicativos 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 aos aplicativos assinados por esses certificados para fazer chamadas para métodos especiais. As operadoras antigas têm uma população grande e estabelecida de SIM, que não é facilmente atualizável. Além disso, as operadoras que não possuem direitos de autoria para novos SIMs (por exemplo, MVNOs que possuem SIMs emitidos por 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 dispositivos para aplicativos de operadoras 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 contidas no TAC são inadequadas para identificar um dispositivo específico.
MSISDN As operadoras podem usar o número de telefone (MSISDN), disponível no TelephonyManager com o grupo de permissão PHONE , para consultar o IMEI em seus sistemas backend. Isto requer um investimento significativo para as transportadoras. As operadoras que mapeiam suas chaves de rede usando IMSI necessitam de recursos técnicos significativos para mudar para MSISDN .

Todos os aplicativos da operadora podem acessar identificadores de dispositivos atualizando o arquivo CarrierConfig.xml com o hash do certificado de assinatura do aplicativo da 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 serão retornadas. Se nenhuma correspondência for encontrada, uma exceção de segurança será retornada.

Para implementar esta solução, as transportadoras DEVEM seguir estes passos:

  1. Atualize CarrierConfig.xml com o hash do certificado de assinatura do aplicativo da operadora e envie um patch .
  2. Solicite aos OEMs que atualizem sua compilação com QPR1+ (recomendado) OU esses patches de plataforma necessários e o patch que contém o arquivo CarrierConfig.xml atualizado da etapa 1 acima.

Implementação

Atualize sua lista de permissões privilegiadas para conceder a permissão READ_PRIVILEGED_PHONE_STATE aos aplicativos privilegiados que exigem acesso a identificadores de dispositivos.

Para saber mais sobre listas de permissões, consulte Lista de permissões de permissões privilegiadas .

Para invocar as APIs afetadas, um aplicativo deve atender a um dos seguintes requisitos:

  • Se o aplicativo for um aplicativo privilegiado pré-carregado, ele precisará da permissão READ_PRIVILEGED_PHONE_STATE declarada em AndroidManifest.xml. O aplicativo também precisa incluir essa permissão privilegiada na lista de permissões.
  • Os aplicativos entregues pelo 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 apresenta o seguinte comportamento:

  • Se o aplicativo for direcionado ao pré-Q e não tiver a permissão READ_PHONE_STATE concedida, SecurityException será acionado. este é o comportamento atual pré-Q, pois essa permissão é necessária para invocar essas APIs.
  • Se o aplicativo for direcionado ao pré-Q e tiver a permissão READ_PHONE_STATE concedida, ele receberá um valor nulo para todas as APIs do TelephonyManager e Build.UNKNOWN para o método Build#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 conjunto de testes de compatibilidade (CTS) inclui testes para verificar o comportamento esperado de acesso ao identificador de dispositivo para aplicativos com privilégios de operadora, proprietários de dispositivos e perfis e aqueles aplicativos que não devem ter acesso a identificadores de dispositivos.

Os testes 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 aplicativos podem ser permitidos 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 incluído 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 CarrierConfig básico que eu possa usar?

Use o seguinte modelo. Isto 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 atualmente. 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 nº 1 só tem privilégios de acesso para o SIM nº 1 e vice-versa.

Como as operadoras convertem o certificado de assinatura de um aplicativo em um hash?

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

  1. Converta a assinatura do certificado de assinatura em uma matriz de bytes usando toByteArray .
  2. Use MessageDigest para converter a matriz de bytes em um hash no tipo 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 valor 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>