Integrar a API Play Integrity para PC ao app

A API Play Integrity para PC ajuda a verificar se os eventos do jogo e as solicitações do servidor vêm de uma instância genuína do Google Play Games para PC em um dispositivo de PC genuíno. Ao detectar dispositivos potencialmente arriscados e emuladores desconhecidos, o servidor de back-end do jogo pode responder com as ações adequadas para evitar trapaças, acesso não autorizado, tráfego fraudulento e abusos.

Pré-requisitos

Etapa 1: decidir como usar a API Play Integrity para PC no jogo

Decida quando você vai chamar a API Play Integrity para PC para receber um veredito de integridade sobre o ambiente. Por exemplo, você pode solicitar um veredito quando o jogo é aberto, quando um jogador faz login ou quando um jogador entra em um jogo multiplayer. Em seguida, decida como você vai lidar com diferentes respostas de integridade. Por exemplo, você pode fazer o seguinte:

  • Coletar a resposta sem ações de aplicação e analisar os dados internamente para entender se é um indicador útil de abuso.
  • Colete a resposta e implemente a lógica no servidor de back-end para permitir que dispositivos que passem nos vereditos de integridade joguem normalmente, enquanto desafiam ou negam o acesso ao tráfego que vem de ambientes suspeitos.
  • Colete a resposta e implemente a lógica no back-end para corresponder jogadores em dispositivos que passam nas verificações de integridade juntos, enquanto corresponde o tráfego vindo de ambientes suspeitos.

Etapa 2: solicitar tokens de integridade no jogo

Aquecer a Play Integrity para PC

Prepare (ou "aqueça") a API Play Integrity para PC, que permite ao Google Play armazenar em cache de forma inteligente informações parciais de atestado no dispositivo para diminuir a latência no caminho crítico quando você faz uma solicitação de veredito de integridade. Você pode fazer isso de forma assíncrona assim que o jogo for aberto para fazer solicitações de integridade sob demanda quando necessário.

void PrepareIntegrityToken(
  const PrepareIntegrityTokenParams & params,
  PrepareIntegrityTokenContinuation continuation
)

Se a operação for bem-sucedida, a continuação será chamada com um PrepareIntegrityTokenResultValue que contém um RequestTokenData a ser usado para solicitar um token de integridade. Esses dados precisam ser armazenados em cache na memória e reutilizados durante a sessão do aplicativo para chamadas de RequestIntegrityToken.

Só faça uma chamada para PrepareIntegrityToken se o aplicativo determinar que é necessário reavaliar completamente o veredito de integridade.

Detalhes
Parâmetros params: parâmetros que contêm um número de projeto do Google Cloud.
continuation: o callback assíncrono para retornar ao provedor de token de integridade.

Confira um snippet de código que mostra como chamar a ação PrepareIntegrityToken:

google::play::integrity::IntegrityClient client_;

google::play::integrity::PrepareIntegrityTokenResult
IntegrityInterface::PrepareIntegrityToken(int64_t cloud_project_number) {
  google::play::integrity::PrepareIntegrityTokenParams params;
  params.cloud_project_number = cloud_project_number;

  auto promise = std::make_shared<
      std::promise<google::play::integrity::PrepareIntegrityTokenResult>>();
  client_.PrepareIntegrityToken(
      params,
      [promise](
          google::play::integrity::PrepareIntegrityTokenResult result) {
        promise->set_value(std::move(result));
      });

  return promise->get_future().get();
}

Solicitar seu token de integridade

Os tokens de integridade são um mecanismo para o jogo verificar se o dispositivo não foi violado. Sempre que o jogo fizer uma solicitação de servidor que você queira verificar se é genuína, solicite um token de integridade e o envie ao servidor de back-end do jogo para descriptografia e verificação.

Ao verificar uma ação do usuário no app com a API Play Integrity para PC, use o campo RequestIntegrityTokenParams::request_hash para mitigar ataques de adulteração. Por exemplo, você pode querer informar a pontuação do jogador ao servidor de back-end do jogo, e seu servidor quer verificar se ela não foi adulterada por um servidor proxy. A Play Integrity para PC pode retornar o valor definido neste campo na resposta de integridade assinada. Sem o requestHash, o token de integridade será vinculado apenas ao dispositivo, mas não à solicitação específica, o que abre a possibilidade de ataque.

void RequestIntegrityToken(
  const RequestIntegrityTokenParams & params,
  RequestIntegrityTokenContinuation continuation
)

Para reduzir a possibilidade de um ataque, quando você solicita um veredito de integridade:

  • Calcule um resumo de todos os parâmetros de solicitação relevantes (por exemplo, SHA256 de uma serialização de solicitações estável) da ação do usuário ou da solicitação do servidor que estiver acontecendo.
  • Defina o campo RequestIntegrityTokenParams::request_hash como o resumo.
Detalhes
Parâmetros params: parâmetros que contêm o RequestTokenData preparado e o hash da solicitação de verificação de integridade.
continuation: o callback assíncrono para retornar os dados.

Confira um snippet de código que mostra como chamar a ação RequestIntegrityToken:

absl::StatusOr<google::play::integrity::RequestIntegrityTokenResult>
IntegrityInterface::RequestIntegrityToken(
    const google::play::integrity::PrepareIntegrityTokenResult&
        prepare_integrity_token_result,
    const std::string& request_hash) {
  // Check if the prepare_integrity_token_result is OK
  if (!prepare_integrity_token_result.ok()) {
    return absl::FailedPreconditionError(
        absl::StrCat("PrepareIntegrityTokenResult is not OK. Error code: ",
                     prepare_integrity_token_result.error_code));
  }

  google::play::integrity::RequestIntegrityTokenParams params{
      .request_token_data =
          prepare_integrity_token_result.request_token_data,
      .request_hash = request_hash};

  auto promise = std::make_shared<std::promise<
      google::play::integrity::RequestIntegrityTokenResult>>();
  client_.RequestIntegrityToken(
      params,
      [promise](google::play::integrity::RequestIntegrityTokenResult result) {
        promise->set_value(std::move(result));
      });

  return promise->get_future().get();
}

Etapa 3: descriptografar e verificar os tokens de integridade no servidor de back-end do jogo

Descriptografar um token de integridade

Depois de solicitar um veredito de integridade, a API Play Integrity fornece um token de resposta criptografado. Para extrair os vereditos de integridade do dispositivo, é necessário descriptografar o token de integridade nos servidores do Google:

  1. Crie uma conta de serviço no projeto do Google Cloud vinculado ao app.
  2. No servidor do app, busque o token de acesso nas credenciais da conta de serviço usando o escopo playintegrity e faça esta solicitação:

    playintegrity.googleapis.com/v1/<var>PACKAGE_NAME</var>:decodePcIntegrityToken -d \
     '{ "integrity_token": "<var>INTEGRITY_TOKEN</var>" }'
    
  3. Leia a resposta JSON.

O payload resultante é um token de texto simples que contém vereditos de integridade e detalhes, além de informações fornecidas pelo desenvolvedor. Um token de integridade descriptografado tem esta aparência:

{
  "requestDetails": {
    "requestPackageName": "com.your.package.name",
    "requestTime": "2025-08-29T13:10:37.285Z",
    "requestHash": "your_request_hash_string"
  },
  "deviceIntegrity": {
    "deviceRecognitionVerdict": [
      "MEETS_PC_INTEGRITY"
    ]
  },
}

Verificar o token de integridade

O campo requestDetails do token de integridade decodificado contém informações sobre a solicitação, incluindo informações fornecidas pelo desenvolvedor no requestHash.

Os campos requestHash e packageName precisam corresponder aos da solicitação original. Portanto, verifique a parte requestDetails do payload JSON, garantindo que o requestPackageName e o requestHash correspondam ao que foi enviado na solicitação original, conforme mostrado no snippet de código abaixo:

const auto& request_details = json_payload["requestDetails"];

if (request_details.value("requestPackageName", "") != <YOUR_PACKAGE_NAME>) {
  // Don't trust the verdicts.
}

// Check for the existence of the request_hash.
// If you set a request hash in the request and it's not present, you shouldn't
// trust the verdicts.
if (!request_details.contains("requestHash")) {
    // Don't trust the verdicts.
}


// The requestHash from request_details needs to match the request hash your
// app provided.
if (request_details.value("requestHash", "") != <PROVIDED_REQUEST_HASH>) {
    // Don't trust the verdicts.
}

// You can read the rest of payload's fields.

Etapa 4: decidir qual ação tomar com base no veredito de integridade

O campo deviceIntegrity pode conter um único valor, deviceRecognitionVerdict. Você pode usar esse valor para determinar se o jogo está sendo executado em um PC que passa nas verificações de integridade do Play (uma resposta MEETS_PC_INTEGRITY). O servidor de back-end do jogo pode coletar essas informações e usá-las para determinar qual ação o jogo deve tomar, como permitir que um evento prossiga ou negar o acesso a tráfego arriscado.

"deviceIntegrity": {
  "deviceRecognitionVerdict": ["MEETS_PC_INTEGRITY"]
}

deviceRecognitionVerdict pode ter estes valores:

MEETS_PC_INTEGRITY
O jogo está sendo executado em um ambiente de PC genuíno, sem adulteração detectada no dispositivo.
Vazio (um valor em branco)
O jogo está sendo executado em um dispositivo que tem sinais de ataque, como hooks de API, ou comprometimento do sistema, como um dispositivo executando uma versão adulterada dos Serviços do Google para computador. Ou, então, o app não está sendo executado em um dispositivo físico, mas sim, por exemplo, em um emulador que falha nas verificações de integridade do Google Play.

Etapa 5: processar códigos de erro

Se o jogo fizer uma solicitação da API Play Integrity para PC e a chamada falhar, ele vai receber um código de erro. Esses erros podem acontecer por vários motivos, como problemas ambientais, como uma conexão de rede ruim, problemas com a integração da API ou atividades maliciosas e ataques ativos.

Códigos de erros que aceitam novas tentativas

Às vezes, a causa desses erros é devido a condições temporárias. Portanto, você precisa repetir a chamada com uma estratégia de espera exponencial.

IntegrityError Descrição do erro Código de erro
kNetworkError Problema de conectividade de rede no dispositivo. 5
kTooManyRequests Muitas solicitações foram feitas no dispositivo. 6
kClientTransientError Um problema temporário com o cliente. 7

Confira mais recomendações sobre estratégias de novas tentativas.

Códigos de erros que não aceitam novas tentativas

É improvável que novas tentativas automáticas ajudem nesses casos. No entanto, uma nova tentativa manual pode ajudar se o usuário resolver a condição que causou o problema.

IntegrityError Descrição do erro Código de erro Ação recomendada
kError Erro fatal durante a ação do SDK. 1 Verifique a implementação da API antes de tentar de novo.
kCloudProjectNumberIsInvalid O número do projeto no Cloud é inválido. 2 Verifique se o número do projeto na nuvem está configurado corretamente no console do Google Cloud e se as solicitações são feitas com o número correto do projeto na nuvem.
kRequestHashTooLong O hash de solicitação é muito longo. 3 Os hashes de solicitação gerados são muito longos. Verifique se eles têm menos de 500 caracteres.
kNoValidPreparedTokenFound Não há um token preparado antes de fazer a solicitação. 4 Chame a ação [PrepareIntegrityToken][prepare-token] antes de fazer a chamada [RequestIntegrityToken][request-integrity-token].
kSdkRuntimeUpdateRequired É necessário atualizar o SDK Play para nativo. 8 Verifique se o cliente do Google Play Services no dispositivo está atualizado e se você está usando a versão mais recente do SDK Play para PC nativo.