Guia de integração da API Play Integrity

Programa de acesso antecipado (EAP, na sigla em inglês)

No momento, a API Play Integrity está disponível por um programa de acesso antecipado. A API ainda está em desenvolvimento e não está disponível para o público geral. Para resolução de problemas e feedback, envie um e-mail para integrity-api-eap@google.com.

Termos de Serviço da API Play Integrity

Ao acessar ou usar a API Play Integrity, você concorda com os Termos de Serviço do kit de desenvolvimento de software da Play Core. Leia e entenda todos os termos e políticas aplicáveis antes de acessar a API.

Visão geral

A API Play Integrity unifica os recursos antiabuso do Google Play, que podem ser usados para detectar tráfego arriscado e fraudulento. Esse tráfego pode ser proveniente de versões não autorizadas do seu app ou jogo, de dispositivos não confiáveis ou de outros ambientes não confiáveis. Ao detectar esse tráfego, é possível responder com a ação adequada para reduzir o abuso, como em casos de fraude, trapaça e acesso não autorizado. A API está disponível para apps e jogos. Os criadores de jogos que usam a API podem assistir a este vídeo introdutório da Conferência de Desenvolvedores do Google para Jogos 2021.

Atualmente, essa API fornece uma resposta assinada e criptografada com as seguintes informações:

imagem da integridade que destaca como ela funciona com dispositivos Android e
            do Google Play
  • Integridade do aplicativo: informa se você está interagindo com seu binário não modificado reconhecido pelo Google Play.
  • Detalhes da conta: informa se a conta de usuário atual é licenciada, o que significa que o usuário comprou ou instalou o app ou jogo no Google Play.
  • Integridade do dispositivo: informa se o app está sendo executado em um dispositivo Android genuíno com o Google Play Services.

Uso da API em níveis superiores

diagrama que ilustra as relações entre o app,
            o back-end dele e a API Play Integrity

Em um nível superior, a API funciona da seguinte maneira:

  1. O back-end do app gera e envia um valor de uso único para ele.
  2. O app chama a API Integrity com esse valor e recebe um token assinado e criptografado com as orientações de integridade do Google Play.
  3. O app envia o token para o back-end.
  4. O back-end do app descriptografa e verifica o token. Em seguida, decide como proceder com base nos sinais contidos no payload do token.
  5. O back-end envia os resultados da decisão para o app.

Considerações sobre segurança

Embora a API Play Integrity ajude a garantir a segurança e proteja contra adulterações, realize toda a descriptografia e a validação em um ambiente de servidor seguro. Quaisquer detalhes de segurança expostos por um app cliente podem ser extraídos e removidos do APK/repositório por um invasor. Especificamente, observe o seguinte:

  • A API precisa ser chamada principalmente para proteger ações não recorrentes e de alto valor que sejam uma parte fundamental da experiência do usuário, como fazer login em um serviço ou participar de um servidor multijogador. Não é recomendado que você busque o token de integridade com muita frequência, especialmente em dispositivos mais antigos, em que é necessário mais tempo para ele ser gerado. Em média, uma chamada por dia para cada usuário ativo é razoável, mas um usuário que realiza várias ações de alto valor em um dia pode justificar várias chamadas.
  • Os valores de uso único precisam ser exclusivos e impossíveis de serem previstos por um invasor.
  • Todas as descriptografias e verificações precisam ser realizadas em um ambiente de servidor seguro. Não descriptografe ou verifique o token recebido no app cliente.
  • Nunca exponha nenhuma chave de descriptografia para o app cliente.
  • Em vez de enviar uma única resposta de aprovação/reprovação do servidor para o app, é melhor enviar vários sinais e resultados de decisão que são mais difíceis de replicar. Por exemplo, você pode usar uma série de respostas relacionadas, como Permitir, Permitir com limites, Permitir com limites após o preenchimento do reCAPTCHA e Negar.

A API Play Integrity é melhor quando usada em conjunto com outros sinais como parte da sua estratégia geral contra abuso, e não como seu único mecanismo antiabuso. Ela precisa ser sempre usada com práticas recomendadas de segurança adequadas para seu app.

Limites de uso da API

As solicitações para a API estão sujeitas a um máximo por dia para cada app, conforme determinado pelo nível de uso atribuído ao app de chamada. Os apps no EAP são atribuídos automaticamente a um nível de uso especial.

O nível do EAP é limitado a cinco milhões de solicitações por dia para cada app. Se você precisar de mais de cinco milhões de solicitações por dia, entre em contato com integrity-api-eap@google.com.

O mesmo app distribuído no Google Play e em outros canais de distribuição e app stores conta como um único app em termos de uso da API. Se você usar um nome de pacote diferente para a distribuição no Google Play e em outras fontes, entre em contato com integrity-api-eap@google.com para registrar o nome do pacote que não é do Play como vinculado ao nome daquele que é.

Outras informações sobre níveis de uso serão fornecidas quando a API for disponibilizada para o público geral. Nesse momento, os apps no nível de uso do EAP serão migrados para níveis públicos.

Pré-requisitos

Requisitos de integração

  • Buscar chaves de token de integridade.
  • Biblioteca Play Core para EAP (core-integrity-1.10.1.aar): faça o download na pasta do Drive.
  • Para a integração do Unity, com o Unity 2017.4.40, 2018.4 ou mais recentes: faça o download de pacotes do Google específicos para EAP na pasta do Drive.
  • Para integração nativa, faça o download da biblioteca Play Core Native específica para EAP (play-core-native-sdk-integrity-eap.zip) na pasta do Drive.

Requisitos do dispositivo

  • Android 4.4 (KitKat, API de nível 19) ou versões mais recentes
  • App Play Store 24.6.31 ou versões mais recentes
  • Google Play Services V19 (12800000) ou versões mais recentes

Buscar chaves de token de integridade

Por motivos de segurança, as chaves recebidas serão criptografadas. Veja as etapas para receber e descriptografar as chaves de token de integridade:

  1. Crie um novo par de chaves públicas/privadas. A chave RSA precisa ser de 2.048 bits.

    $ openssl genrsa -aes128 -out private.pem 2048
    $ openssl rsa -in private.pem -pubout > public.pem
    
  2. Envie a chave pública para integrity-api-eap@google.com e aguarde o recebimento das chaves de token de integridade criptografadas (integrity_token_keys.enc).

  3. Use sua chave privada para descriptografar as chaves do token de integridade.

    $ openssl rsautl -decrypt -oaep -inkey private.pem \
        -in integrity_token_keys.enc > integrity_token_keys.txt
    $ cat integrity_token_keys.txt
    DECRYPTION_KEY=XXXXXXXXXXXXX
    VERIFICATION_KEY=YYYYYYYYYYYYY
    

Integrar a Play Core ao app

A biblioteca Play Core é a interface do ambiente de execução do seu app com a Google Play Store. Para integrar a Play Core ao seu app, siga as instruções em Visão geral da biblioteca Google Play Core.

Java ou Kotlin

Durante o EAP, em vez de usar a versão Maven da biblioteca do Google, use a versão disponível na seção de pré-requisitos.

Se você estiver usando um repositório Maven local, adicione a seguinte dependência ao arquivo build.gradle do app:

implementation com.google.android.play:core-integrity

Unity

Em vez de usar a versão mais recente do plug-in do Unity para o Google Play, importe os arquivos .unitypackage ou .tgz disponíveis na seção de pré-requisitos para seu projeto do Unity. Para instruções de instalação, consulte Instalar pacotes do Google para o Unity.

Native

Consulte o guia de configuração do ambiente de desenvolvimento da biblioteca Play Core Native.

Gerar um valor de uso único

Um valor de uso único é um token de uso único gerado especificamente para uma solicitação. Os valores de uso único protegem as solicitações à API Play Integrity contra repetições. Por exemplo, se um usuário receber um token da API Play Integrity para uma ação protegida específica, não poderá reutilizá-lo em outras ações protegidas mais tarde, no que é conhecido comoataque de repetição. Por isso, os valores de uso único precisam ser exclusivos e impossíveis de prever.

A forma recomendada de criar um valor de uso único é solicitar que o servidor de back-end seguro gere um número aleatório criptograficamente seguro que não inclua informações específicas do cliente. Uma alternativa menos segura, mas aceitável, é combinar dados como um carimbo de data/hora ou ID de usuário, calcular um hash criptográfico usando esses valores e enviá-lo como o valor de uso único para o app cliente.

Os valores de uso único são transmitidos como estão aos sistemas do Google. Portanto, é fundamental garantir que nenhuma PII ou outros dados sensíveis sejam incluídos direta ou indiretamente no valor de uso único. Em alguns casos, mesmo dados com hash podem ser usados teoricamente para coletar dados sensíveis. Assim, para apps especialmente confidenciais, não é recomendado depender de dados sensíveis.

É possível gerar valores de uso único no servidor ou no cliente. Ainda assim, não podemos presumir que o cliente seja confiável, porque ele pode estar sob o controle de um invasor. Dessa forma, gerar o valor de uso único aleatoriamente no lado do servidor é mais seguro do que no lado do cliente.

Valor de uso único gerado pelo servidor

A melhor solução é gerar valores de uso único com um gerador de números aleatórios criptograficamente seguros em um ambiente de servidor seguro para cada solicitação de entrada do cliente. O diagrama a seguir mostra um exemplo:

exemplo de geração de valor de uso único usando um servidor

O valor de uso único é exclusivo e impossível de prever. Portanto, essa abordagem oferece uma forte garantia de que não é possível repetir a solicitação.

Valor de uso único gerado pelo cliente

Alguns clientes podem não conseguir reter todas as solicitações de entrada no lado do servidor ou não tolerar o atraso de uma viagem de ida e volta extra. Para esses casos, o exemplo a seguir demonstra outra solução que troca algumas das garantias de repetição para simplificar. O exemplo gera hash dos parâmetros de solicitação, incluindo o carimbo de data/hora, na solicitação:

exemplo de geração de valor de uso único em um dispositivo cliente

O carimbo de data/hora precisa ser incluído nos parâmetros de solicitação. Assim, solicitações idênticas não resultam no mesmo valor de uso único, garantindo que cada valor seja exclusivo. Ainda assim, como o carimbo de data/hora e os parâmetros de solicitação são gerados no cliente, e você não sabe se o cliente está sob o controle de um invasor, considere que comportamentos adversos são possíveis.

Escolha a técnica de geração de valores de uso único com base no valor da ação que você está protegendo e da ameaça percebida ao aplicativo.

Receber o token de integridade

Após gerar um valor de uso único, é possível conseguir um token de integridade criando primeiro um IntegrityManager, conforme mostrado nos exemplos a seguir. Use o gerenciador para chamar requestIntegrityToken(), fornecendo o valor de uso único com o método setNonce() no builder IntegrityTokenRequest associado.

Exemplo da linguagem de programação Java

// Receive the nonce from the secure server.
String nonce = ...

// Create an instance of a manager.
IntegrityManager integrityManager =
    IntegrityManagerFactory.create(applicationContext);

// Request the integrity token by providing a nonce.
Task<IntegrityTokenResponse> integrityTokenResponse =
    integrityManager
      .requestIntegrityToken(
          IntegrityTokenRequest.builder().setNonce(nonce).build());

Exemplo do Unity

IEnumerator RequestIntegrityTokenCoroutine()
{
    // Receive the nonce from the secure server.
    var nonce = ...

    // Create an instance of a manager.
    var integrityManager = new IntegrityManager();

    // Request the integrity token by providing a nonce.
    var tokenRequest = new IntegrityTokenRequest(nonce);
    var requestIntegrityTokenOperation =
        integrityManager.RequestIntegrityToken(tokenRequest);

    // Wait for PlayAsyncOperation to complete.
    yield return requestIntegrityTokenOperation;

    // Check the resulting error code.
    if (requestIntegrityTokenOperation.Error != IntegrityErrorCode.NoError)
    {
        AppendStatusLog("IntegrityAsyncOperation failed with error: " +
                        requestIntegrityTokenOperation.Error);
        yield break;
    }

    // Get the response.
    var tokenResponse = requestIntegrityTokenOperation.GetResult();
}

Exemplo nativo

/// Create an IntegrityTokenRequest opaque object.
const char* nonce = RequestNonceFromServer();
IntegrityTokenRequest* request;
IntegrityTokenRequest_create(&request);
IntegrityTokenRequest_setNonce(request, nonce);

/// Prepare an IntegrityTokenResponse opaque type pointer and call
/// IntegerityManager_requestIntegrityToken().
IntegrityTokenResponse* response;
IntegrityErrorCode error_code = IntegrityManager_requestIntegrityToken(request, &response);

...

/// Proceed to polling iff error_code == INTEGRITY_NO_ERROR
if (error_code != INTEGRITY_NO_ERROR) {
    /// Remember to call the *_destroy() functions.
    return;
}

...

/// Use polling to wait for the async operation to complete.
IntegrityResponseStatus response_status;
IntegrityErrorCode error_code = IntegrityTokenResponse_getStatus(response, &response_status);
if (error_code == INTEGRITY_NO_ERROR && response_status == INTEGRITY_RESPONSE_COMPLETED) {
    const char* integrity_token = IntegrityTokenResponse_getToken(response);
    SendTokenToServer(integrity_token);
}

...

/// Remember to free up resources.
IntegrityTokenRequest_destroy(request);
IntegrityTokenResponse_destroy(response);
IntegrityManager_destroy();

Descriptografar o token e verificar a integridade

O valor de uso único fornecido se torna parte do token de resposta assinado retornado. Você pode buscar o token retornado usando o método IntegrityTokenResponse#token(). Descriptografe e verifique o token retornado em um ambiente de servidor seguro e nunca no app.

Formato do token

O token é um Token da Web JSON (JWT, na sigla em inglês) aninhado, ou seja, Criptografia JSON da Web (JWE, na sigla em inglês) de Assinatura JSON da Web (JWS, na sigla em inglês). Os componentes da JWE e da JWS são representados usando a serialização compacta.

Os algoritmos de criptografia e assinatura têm suporte em várias implementações de JWT:

  • A JWE usa A256KW para alg e A256GCM para enc.
  • A JWS usa ES256.

O exemplo a seguir mostra como decodificar a chave AES e a chave pública EC codificada em DER para verificação de assinatura do Play Console ou enviar por e-mail, no caso de chaves específicas da linguagem (Java, no nosso caso) no back-end do app. Observe que as chaves são codificadas em base64 usando sinalizações padrão.

// base64OfEncodedDecryptionKey is provided through Play Console / over email.
byte[] decryptionKeyBytes =
    Base64.decode(base64OfEncodedDecryptionKey, Base64.DEFAULT);
// Deserialized encryption (symmetric) key.
SecretKey decryptionKey =
    new SecretKeySpec(
        decryptionKeyBytes,
        /* offset= */ 0,
        AES_KEY_SIZE_BYTES,
        AES_KEY_TYPE);

// base64OfEncodedVerificationKey is provided through
//  Play Console / over email.
byte[] encodedVerificationKey =
    Base64.decode(base64OfEncodedVerificationKey, Base64.DEFAULT);
// Deserialized verification (public) key.
PublicKey verificationKey =
    KeyFactory.getInstance(EC_KEY_TYPE)
        .generatePublic(new X509EncodedKeySpec(encodedVerificationKey));

Em seguida, use essas chaves para descriptografar o token de integridade (parte JWE) e, em seguida, verificar e extrair a parte JWS aninhada.

JsonWebEncryption jwe =
 (JsonWebEncryption)JsonWebStructure.fromCompactSerialization(integrityToken);
jwe.setKey(decryptionKey);

// This also decrypts the JWE token.
String compactJws = jwe.getPayload();

JsonWebSignature jws =
    (JsonWebSignature) JsonWebStructure.fromCompactSerialization(compactJws);
jws.setKey(verificationKey);

// This also verifies the signature.
String payload = jws.getPayload();

O payload resultante é um token de texto simples que contém sinais de integridade.

Você também precisa verificar a parte requestDetails do payload JSON, garantindo que o valor de uso único e o nome do pacote correspondam ao que foi enviado na solicitação original e que o carimbo de data/hora não esteja desatualizado.

JSONObject requestDetails =
    new JSONObject(payload).getJSONObject("requestDetails");
String requestPackageName =
    requestDetails.getString("requestPackageName");
String nonce = requestDetails.getString("nonce");
long timestampMillis = requestDetails.getLong("timestampMillis");
long currentTimestampMillis = ...;

if (!requestPackageName.equals(expectedPackageName)
    // See "Generate nonce" section of the doc on how to store/compute
    // the expected nonce.
    || !nonce.equals(expectedNonce)
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
  // The token is invalid!
  ...
}

Formato do payload retornado

O payload é JSON em texto simples e contém sinais de integridade e informações fornecidas pelo desenvolvedor.

A estrutura geral do payload é a seguinte:

{
    requestDetails: { ... }
    appIntegrity: { ... }
    deviceIntegrity: { ... }
    accountDetails: { ... }
}

As seções a seguir descrevem cada campo em mais detalhes.

Campo de detalhes da solicitação

O campo requestDetails contém informações fornecidas na solicitação, incluindo o valor de uso único. Esses valores precisam corresponder aos da solicitação original.

requestDetails: {
    // Application package name this attestation was requested for.
    // Note that this field might be spoofed in the middle of the
    //  request.
    requestPackageName: "com.package.name"
    // base64-encoded web-safe no-wrap nonce provided by the developer.
    nonce: "aGVsbG8gd29scmQgdGhlcmU"
    // The timestamp in milliseconds when the request was made
    //  (computed on the server).
    timestampMillis: 1617893780
}

Campo de integridade do aplicativo

O campo appIntegrity contém informações relacionadas ao pacote.

appIntegrity: {
    // PLAY_RECOGNIZED, UNRECOGNIZED_VERSION, or UNEVALUATED.
    appRecognitionVerdict: "PLAY_RECOGNIZED"
    // The package name of the app.
    // This field is populated iff appRecognitionVerdict != UNEVALUATED.
    packageName: "com.package.name"
    // The sha256 digest of app certificates on device.
    // This field is populated iff appRecognitionVerdict != UNEVALUATED.
    certificateSha256Digest: ["6a6a1474b5cbbb2b1aa57e0bc3"]
    // The version of the app.
    // This field is populated iff appRecognitionVerdict != UNEVALUATED.
    versionCode: 42
}

appRecognitionVerdict pode ter os seguintes valores:

  • PLAY_RECOGNIZED: o app e o certificado correspondem às versões distribuídas pelo Google Play.
  • UNRECOGNIZED_VERSION: o nome do certificado ou do pacote não corresponde aos registros do Google Play.
  • UNEVALUATED: a integridade do aplicativo não foi avaliada. Um requisito necessário foi perdido, por exemplo, o dispositivo não é confiável o suficiente.

Campo de integridade do dispositivo

O campo deviceIntegrity contém um único valor, deviceRecognitionVerdict, que representa a forma como um dispositivo pode garantir a integridade do app.

deviceIntegrity: {
    // "MEETS_DEVICE_INTEGRITY" is one of several possible values.
    deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
}

Por padrão, deviceRecognitionVerdict pode ter um dos seguintes identificadores:

  • MEETS_DEVICE_INTEGRITY: o app está em execução em um dispositivo Android que usa os Serviços do Google Mobile com o Google Play Services. O dispositivo é aprovado nas verificações de integridade do sistema e atende aos requisitos de suporte do Android.
  • MEETS_VIRTUAL_INTEGRITY: o app é executado em um ambiente virtual do Android com o Google Play Services, como o Android no PC (AoPC). O ambiente atende aos principais requisitos de compatibilidade do Android e é aprovado nas verificações de integridade do Google Play. Se você não está participando do Programa de acesso antecipado do Android no PC, ignore este identificador.
  • Sem identificador (por exemplo, um valor em branco): o app está sendo executado em um dispositivo que tem sinais de ataque (como hook de API) ou comprometimento do sistema (como ter acesso root) ou o app está em execução em um dispositivo não físico (como um emulador) que não é aprovado nas verificações de integridade do Google Play.

Os parceiros podem enviar um e-mail para integrity-api-eap@google.com para ativar o recebimento de outros identificadores possíveis em deviceRecognitionVerdict:

  • MEETS_BASIC_INTEGRITY: o app está sendo executado em um dispositivo que é aprovado nas verificações básicas de integridade do sistema. O dispositivo pode não atender aos requisitos de compatibilidade do Android e não ser aprovado para executar o Google Play Services. Por exemplo, o dispositivo pode estar executando uma versão não reconhecida do Android, ter um carregador de inicialização desbloqueado ou não ter sido certificado pelo fabricante.
  • MEETS_STRONG_INTEGRITY: o app está sendo executado em um dispositivo Android que usa os Serviços do Google Mobile com o Google Play Services e tem uma forte garantia de integridade do sistema, como um keystore protegido por hardware. O dispositivo é aprovado nas verificações de integridade do sistema e atende aos requisitos de suporte do Android.

A resposta de integridade poderá incluir vários identificadores para o mesmo dispositivo se todos os critérios do identificador forem atendidos. Ao escolher receber vários identificadores, você pode criar uma estratégia de aplicação com base em diferentes níveis de confiabilidade do dispositivo.

Por exemplo, considere um dispositivo que retorna MEETS_BASIC_INTEGRITY, MEETS_DEVICE_INTEGRITY e MEETS_STRONG_INTEGRITY. Esse dispositivo pode ser mais confiável do que outro que retorna apenas MEETS_BASIC_INTEGRITY, e a forma como você responde pode ser adaptada de acordo com isso.

Determinadas condições de ambiente, como uma conexão lenta de Internet ou um dispositivo sobrecarregado, podem causar falhas na verificação de integridade do dispositivo. Isso pode fazer com que nenhum identificador seja gerado para um dispositivo que é confiável, não fossem essas condições. Para reduzir essas situações, inclua uma opção para tentar novamente.

Campo de detalhes da conta

O campo accountDetails contém um único valor, licensingVerdict, que representa o status de licenciamento/titularidade do app.

accountDetails: {
    // This field can be LICENSED, UNLICENSED, or UNEVALUATED.
    licensingVerdict: "LICENSED"
}

licensingVerdict pode ter os seguintes valores:

  • LICENSED: o usuário tem titularidade do app, por exemplo, ele o instalou ou comprou no Google Play ou no Play Pass.
  • UNLICENSED: o usuário não tem a titularidade do app, por exemplo, ele transferiu o app por sideload e/ou nunca o comprou no Google Play.
  • UNEVALUATED: os detalhes de licenciamento não foram avaliados porque um requisito necessário foi perdido, por exemplo, o dispositivo não é confiável o suficiente ou o Google Play não reconhece o aplicativo.

Códigos de erro

Task<IntegrityTokenResponse> integrityTokenResponse = ...;
integrityTokenResponse.addOnFailureListener(error -> ...);

A tabela a seguir lista os erros que a API pode retornar e as próximas etapas sugeridas.

Código do erro Descrição O que fazer
API_NOT_AVAILABLE A API Integrity não está disponível. A versão da Play Store pode ser antiga, ou o aplicativo pode não estar na lista de permissões para uso da API.
  1. Confira se o app tem permissão para usar a API.
  2. Peça para o usuário atualizar o app Play Store.
PLAY_STORE_NOT_FOUND Nenhum app oficial da Google Play Store foi encontrado no dispositivo. Peça ao usuário para instalar uma versão adequada da Play Store.
NETWORK_ERROR Nenhuma rede foi encontrada. Peça ao usuário para conferir a conectividade da rede.
PLAY_STORE_ACCOUNT_NOT_FOUND Nenhuma conta da Play Store foi encontrada no dispositivo. Peça para o usuário fazer autenticação na Google Play Store.
APP_NOT_INSTALLED O app de chamada não está instalado. Há algo de errado, possivelmente um ataque. Não há soluções possíveis.
PLAY_SERVICES_NOT_FOUND O Google Play Services está indisponível ou precisa ser atualizado. Peça ao usuário para instalar ou atualizar o Google Play Services.
APP_UID_MISMATCH O UID do app de chamada (ID do usuário) não corresponde ao do gerenciador de pacotes. Há algo de errado, possivelmente um ataque. Não há soluções possíveis.
TOO_MANY_REQUESTS O app de chamada está fazendo muitas solicitações à API e foi limitado. Tente novamente com uma espera exponencial.
CANNOT_BIND_TO_SERVICE Falha ao vincular ao serviço na Play Store. Isso pode ocorrer porque uma versão antiga da Play Store está instalada no dispositivo. Peça para o usuário atualizar a Play Store.
NONCE_TOO_SHORT O valor de uso único é muito curto. O valor de uso único precisa ter um mínimo de 16 bytes (antes da codificação base64). Tente novamente com um valor de uso único mais longo.
NONCE_TOO_LONG O valor de uso único é muito longo. O valor de uso único precisa ter menos que 500 bytes antes da codificação base64. Tente novamente com um valor de uso único mais curto.
GOOGLE_SERVER_UNAVAILABLE Erro desconhecido do servidor interno do Google. Tente novamente com uma espera exponencial. Registre um bug, se necessário.
NONCE_IS_NOT_BASE64 O valor de uso único não tem o formato de base64, com segurança na Web e sem wrapper. Tente novamente com o formato de uso único correto.
INTERNAL_ERROR Erro interno desconhecido. Tente novamente com uma espera exponencial. Registre um bug, se necessário.

Códigos de erro nativos

O prefixo INTEGRITY_ é anexado aos códigos de erro nativos para evitar possíveis conflitos de nomenclatura. Além dos códigos de erro listados acima, a API nativa também inclui os seguintes códigos de erro:

Código do erro Descrição O que fazer
INTEGRITY_INITIALIZATION_NEEDED O IntegrityManager não foi inicializado. Invoque o IntegrityManager_init() primeiro.
INTEGRITY_INITIALIZATION_FAILED Ocorreu um erro ao inicializar a API Integrity. Tente novamente com uma espera exponencial. Registre um bug, se necessário.
INTEGRITY_INVALID_ARGUMENT Um argumento inválido foi transmitido para a API Integrity. Tente novamente com o argumento correto.

Proteção da integridade no momento da instalação (EAP)

Os desenvolvedores do programa de acesso antecipado da API Play Integrity também são convidados a participar do programa de acesso antecipado à proteção da integridade no momento da instalação para fortalecer a estratégia antiabuso. A proteção no momento da instalação não exige nenhum trabalho do desenvolvedor após o envio dos requisitos de instalação. Seu app fica mais protegido quando você combina a proteção no momento da instalação com a verificação da integridade dele durante a execução usando a API Play Integrity.

Visão geral

Com a proteção de integridade no momento da instalação, é possível reduzir as instalações de versões desconhecidas e não autorizadas do seu app ou jogo. Primeiro, especifique os requisitos de instalação para o nome do pacote do seu app. Em seguida, sempre que um app com seu nome de pacote for instalado por qualquer fonte em um dispositivo com Android 11 ou versões mais recentes e licença dos Serviços Google Mobile, a plataforma Android avaliará o app em relação a uma cópia off-line dos requisitos de instalação. O não cumprimento dos requisitos resultará em um erro de verificação de instalação.

Seus requisitos de instalação

Para usar a proteção no momento da instalação, é necessário fornecer uma lista de certificados de assinatura autorizados com o nome do pacote do seu app, incluindo certificados de depuração, para garantir a continuidade dos testes. Quando o app é instalado com um dos certificados de assinatura, a instalação continua normalmente. Quando o app tem um certificado de assinatura desconhecido, a instalação falha com um erro de verificação de instalação.

Há outros dois requisitos de instalação opcionais que podem ser solicitados:

  • Você pode exigir que o nome do seu pacote nunca seja instalado usando o adb.
  • Você pode exigir que o app sempre esteja pré-instalado. Em outras palavras, ele não pode ser uma instalação recente.

Outras considerações

Esteja ciente das seguintes considerações ao usar a proteção no momento da instalação:

  • A proteção de integridade no momento da instalação confere todas as instalações de qualquer origem em dispositivos com licença dos Serviços Google Mobile que executam o Google Play Services e o Android 11 (API de nível 30) ou versões mais recentes. A proteção no momento da instalação não pode proteger instalações de apps em dispositivos Android modificados ou com acesso root.
  • Lembre-se de fornecer todos os certificados de assinatura permitidos usados para seu app. Se qualquer app store autorizada assinar novamente seu app, inclua esses certificados de assinatura na lista de permissões. Com relação a testes, é possível enviar certificados de assinatura de desenvolvimento como certificados de assinatura autorizados ou usar o Compartilhamento interno de apps para instalar suas versões de teste, porque as instalações feitas por esse recurso são permitidas.
  • Os requisitos de instalação novos, atualizados ou removidos levam algum tempo para serem propagados para os dispositivos. Eles podem levar até duas semanas para serem enviados e são recebidos pelos dispositivos em momentos diferentes, dependendo das configurações de atualização de cada um deles e do acesso aos dados e ao Wi-Fi. O Google Play Services tentará novamente várias vezes atualizar os requisitos se eles não puderem ser propagados inicialmente.
  • Se os usuários tentarem instalar um app negado devido aos requisitos de instalação, a plataforma Android gerará uma INSTALL_FAILED_VERIFICATION_FAILURE, que será interpretada e exibida na IU com base no instalador específico ou como uma mensagem de erro durante o sideload.

Solicitar proteção no momento da instalação

Para participar do EAP de proteção de integridade no momento da instalação, envie seus requisitos de instalação usando este formulário do Google. Para apps novos, a proteção no momento da instalação se aplica a todos os números de versão. Para os apps existentes, a proteção é aplicada começando pelo número da versão que você especificar.

Para remover seu app do EAP de proteção de integridade no momento da instalação, entre em contato com seu gerente de parcerias do Google. Os requisitos de instalação removidos levam tempo para serem propagados para os dispositivos.

Mais ferramentas de proteção da integridade do Google Play

Além da API Play Integrity, use as ferramentas de proteção de integridade a seguir como parte da estratégia antiabuso.

Excluir dispositivos não confiáveis da distribuição

Você pode impedir que seu app esteja disponível para instalação no Google Play em dispositivos que não foram aprovados nas verificações de integridade. Essa opção impede que dispositivos desconhecidos e não confiáveis façam o download do app no Google Play. Mas se o usuário tiver acesso a um ou mais arquivos APK, ele ainda poderá instalar o app diretamente.

Para configurar regras de exclusão de dispositivos:

  1. Acesse a página Catálogo de dispositivos no Play Console.
  2. No menu suspenso Dispositivos compatíveis, escolha Dispositivos excluídos.
  3. No canto superior direito, selecione Gerenciar regras de exclusão.
  4. Ao lado de API SafetyNet Attestation, selecione uma opção:
    • Não excluir: selecionada por padrão.
    • Excluir falhas básicas de integridade: isso equivale a excluir dispositivos que não retornam MEETS_BASIC_INTEGRITY na resposta da API Play Integrity.
    • Excluir tudo: isso equivale a excluir dispositivos que não retornam MEETS_DEVICE_INTEGRITY na resposta da API Play Integrity.
  5. Clique em Aplicar.

Proteção automática da integridade

A Proteção automática da integridade (AIP, na sigla em inglês) é uma alternativa de um clique para a API Play Integrity que protege apps e jogos que podem ser executados off-line. Com a AIP, o Google Play adiciona verificações de ambiente de execução ao código do app para restringir a modificação e a redistribuição e, com técnicas avançadas de ofuscação e antiengenharia reversa, faz com que elas sejam difíceis de remover. Se a verificação do instalador resultar em um erro, os usuários poderão fazer o download do app no Google Play. Se a verificação de modificações resultar em um erro, o app não será executado.

A AIP pode ser combinada com a API Play Integrity como parte da estratégia antiabuso para dificultar que seu app modificado seja reempacotado e redistribuído pelos invasores. Saiba mais em nosso guia da Proteção automática da integridade.

Para solicitar acesso à AIP, entre em contato com seu gerente de parcerias do Google. Assim que sua conta tiver acesso, você poderá ativar e desativar a AIP para seu app na página Integridade do app no Play Console.

Feedback

Para resolução de problemas e feedback, envie um e-mail para integrity-api-eap@google.com.

Registro de mudanças no guia de integração

Versão Descrição Data
2.0.0 17/08/21
1.1.0
  • Foi acrescentado um link para o vídeo de apresentação na visão geral.
  • A API nativa foi adicionada à pasta de download.
  • Foram adicionadas informações sobre o uso de um nome de pacote diferente dentro e fora do Google Play nos limites de uso da API.
  • O Android no PC (AoPC, na sigla em inglês) foi acrescentado como um exemplo de identificador virtual no campo de integridade do dispositivo.
14/07/21
1.0.1
  • Foram acrescentados detalhes sobre a API nativa e códigos de erro.
06/07/21
1.0.0
  • Versão inicial.
02/07/21