Интегрируйте Play Integrity для ПК в свое приложение

Play Integrity для ПК помогает проверить, что игровые события и запросы к серверу поступают от подлинного экземпляра Google Play Games для ПК на подлинном устройстве. Выявляя потенциально опасные устройства и неизвестные эмуляторы, серверная часть вашей игры может предпринять соответствующие действия для предотвращения мошенничества, несанкционированного доступа, мошеннического трафика и злоупотреблений.

Предварительные требования

Шаг 1: Решите, как вы будете использовать Play Integrity для ПК в своей игре.

Определите, когда вы будете обращаться в службу проверки целостности среды Play Integrity для ПК, чтобы получить заключение о целостности среды. Например, вы можете запросить заключение при запуске игры, при входе игрока в систему или при присоединении игрока к многопользовательской игре. Затем решите, как вы будете обрабатывать различные ответы службы проверки целостности. Например, вы можете:

  • Соберите полученные ответы, не прибегая к каким-либо принудительным мерам, и проанализируйте данные внутри компании, чтобы понять, являются ли они полезным сигналом о злоупотреблениях.
  • Соберите ответ и реализуйте на своем бэкэнде логику, позволяющую устройствам, прошедшим проверку целостности, играть в вашу игру в обычном режиме, одновременно проверяя или запрещая доступ к трафику, поступающему из подозрительных сред.
  • Соберите ответ и реализуйте на бэкэнде логику для сопоставления игроков на устройствах, прошедших проверку целостности, а также для сопоставления трафика, поступающего из подозрительных сред.

Шаг 2: Запросите токены целостности в своей игре.

Проверка целостности игры на ПК.

Подготовьте (или «прогрейте») Play Integrity для ПК, которая позволяет Google Play интеллектуально кэшировать частичную информацию о подтверждении целостности на устройстве, чтобы уменьшить задержку на критическом пути при запросе на проверку целостности. Вы можете сделать это асинхронно сразу после запуска игры, чтобы отправлять запросы на проверку целостности по мере необходимости.

void PrepareIntegrityToken(
  const PrepareIntegrityTokenParams & params,
  PrepareIntegrityTokenContinuation continuation
)

В случае успеха будет вызвано продолжение с объектом PrepareIntegrityTokenResultValue, содержащим RequestTokenData , который следует использовать для запроса токена целостности. Эти данные должны быть кэшированы в памяти и повторно использованы в течение всего сеанса приложения для вызовов RequestIntegrityToken .

Вызов функции PrepareIntegrityToken следует производить только в том случае, если ваше приложение сочтет необходимым полностью пересмотреть решение о проверке целостности.

Подробности
Параметры params : Параметры, содержащие номер проекта Google Cloud.
continuation : Асинхронный коллбэк для возврата поставщика токенов целостности.

Ниже приведён фрагмент кода, демонстрирующий, как следует вызывать действие 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();
}

Запросить токен целостности

Токены целостности — это механизм, позволяющий вашей игре проверить, не было ли устройство подвергнуто несанкционированному вмешательству. Всякий раз, когда ваша игра отправляет запрос к серверу, подлинность которого вы хотите проверить, вы можете запросить токен целостности, а затем отправить его на серверную часть вашей игры для расшифровки и проверки.

При проверке действий пользователя в вашем приложении с помощью Play Integrity API для ПК вы можете использовать поле RequestIntegrityTokenParams::request_hash для защиты от атак с целью подделки. Например, вы можете захотеть сообщить счет игрока на сервер вашей игры, и ваш сервер хочет убедиться, что этот счет не был изменен прокси-сервером. Play Integrity для ПК может вернуть значение, установленное в этом поле, в подписанном ответе проверки целостности. Без requestHash токен целостности будет привязан только к устройству, но не к конкретному запросу, что открывает возможность для атаки.

void RequestIntegrityToken(
  const RequestIntegrityTokenParams & params,
  RequestIntegrityTokenContinuation continuation
)

Чтобы снизить вероятность атаки при запросе заключения о целостности:

  • Вычислите дайджест всех соответствующих параметров запроса (например, SHA256 стабильной сериализации запроса) на основе действия пользователя или запроса к серверу.
  • Установите поле RequestIntegrityTokenParams::request_hash в значение дайджеста.
Подробности
Параметры params : Параметры, содержащие подготовленные данные RequestTokenData и хэш запроса проверки целостности.
continuation : Асинхронный коллбэк для возврата данных.

Ниже приведён фрагмент кода, демонстрирующий вызов действия 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();
}

Шаг 3: Расшифруйте и проверьте токены целостности на серверной части вашей игры.

Расшифровка токена целостности

После запроса на подтверждение целостности устройства API Play Integrity предоставляет зашифрованный токен ответа. Для получения подтверждения целостности устройства необходимо расшифровать токен целостности на серверах Google:

  1. Создайте учетную запись службы в проекте Google Cloud, которая будет связана с вашим приложением.
  2. На сервере вашего приложения получите токен доступа из учетных данных вашей сервисной учетной записи, используя область действия playintegrity, и выполните следующий запрос:

    playintegrity.googleapis.com/v1/<var>PACKAGE_NAME</var>:decodePcIntegrityToken -d \
     '{ "integrity_token": "<var>INTEGRITY_TOKEN</var>" }'
    
  3. Прочитайте JSON-ответ.

В результате получается токен в открытом текстовом виде, содержащий заключения о целостности и подробную информацию, а также данные, предоставленные разработчиком. Расшифрованный токен целостности выглядит следующим образом:

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

Проверьте токен целостности.

Поле requestDetails декодированного токена целостности содержит информацию о запросе, включая предоставленную разработчиком информацию в поле requestHash .

Поля requestHash и packageName должны совпадать с полями исходного запроса. Поэтому проверьте часть requestDetails в JSON-данных, убедившись, что поля requestPackageName и requestHash соответствуют тем, что были отправлены в исходном запросе, как показано в следующем фрагменте кода:

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.

Шаг 4: Примите решение о дальнейших действиях, исходя из заключения о добросовестности.

Поле deviceIntegrity может содержать одно значение — deviceRecognitionVerdict . Это значение позволяет определить, запущена ли ваша игра на ПК, прошедшем проверку целостности Play (ответ MEETS_PC_INTEGRITY ). Поле accountDetails содержит одно значение — appLicensingVerdict . Это значение позволяет определить, получил ли пользователь лицензию от Play. Сервер вашей игры может собирать эту информацию и использовать её для определения необходимых действий, например, разрешения игрового события или запрета доступа к опасному трафику.

"deviceIntegrity": {
  "deviceRecognitionVerdict": ["MEETS_PC_INTEGRITY"]
}
"accountDetails": {
  "appLicensingVerdict": "LICENSED"
}

Вердикты о целостности устройства

deviceRecognitionVerdict может принимать следующие значения:

MEETS_PC_INTEGRITY
Игра запущена в реальной среде ПК, где никаких манипуляций на устройстве обнаружено не было.
Пустое значение (пустой символ)
Игра запущена на устройстве, имеющем признаки атаки (например, перехват API) или компрометации системы (например, на устройстве установлена ​​модифицированная версия Google Desktop Services), либо приложение запущено не на физическом устройстве (например, на эмуляторе, не прошедшем проверку целостности Google Play).

Вердикты по деталям учетной записи

appLicensingVerdict может принимать следующие значения:

LICENSED
У пользователя есть права на использование приложения. Другими словами, пользователь установил или обновил ваше приложение из Google Play на своем устройстве.
UNLICENSED
У пользователя нет прав на использование приложения. Это происходит, например, когда пользователь устанавливает ваше приложение через сторонние ресурсы или не загружает его из Google Play.
UNEVALUATED
Информация о лицензировании не была проверена, поскольку было упущено необходимое требование. Это могло произойти по нескольким причинам, в том числе по следующим:
  • Данное устройство недостаточно надежно.
  • Версия приложения, установленного на вашем устройстве, неизвестна Google Play.
  • Пользователь не авторизован в Google Play.

Шаг 5: Обработка кодов ошибок

Если ваша игра отправляет запрос Play Integrity for PC, и вызов завершается неудачей, игра получает код ошибки. Эти ошибки могут возникать по разным причинам, например, из-за проблем с окружающей средой, таких как плохое сетевое соединение, проблемы с интеграцией API или вредоносная активность и активные атаки.

Повторяемые коды ошибок

Причиной этих ошибок иногда являются переходные процессы, поэтому следует повторить вызов, используя стратегию экспоненциальной задержки.

IntegrityError Описание ошибки Код ошибки
kNetworkError Проблема с подключением к сети на устройстве. 5
kTooManyRequests Устройство отправило слишком много запросов. 6
kClientTransientError Временная проблема с клиентом. 7

Дополнительные рекомендации по стратегиям повторных попыток можно найти здесь.

Коды ошибок, которые невозможно повторить

Автоматические повторные попытки в таких случаях вряд ли помогут. Однако ручная повторная попытка может помочь, если пользователь устранит причину, вызвавшую проблему.

IntegrityError Описание ошибки Код ошибки Рекомендуемые действия
kError Критическая ошибка во время работы SDK. 1 Перед повторной попыткой проверьте реализацию вашего API.
kCloudProjectNumberIsInvalid Номер облачного проекта недействителен. 2 Убедитесь, что номер вашего облачного проекта правильно указан в консоли Google Cloud и что запросы отправляются с правильным номером облачного проекта.
kRequestHashTooLong Хэш запроса слишком длинный. 3 Хэши сгенерированных запросов слишком длинные. Убедитесь, что они содержат менее 500 символов.
kNoValidPreparedTokenFound Перед отправкой запроса на получение токена подготовленный токен отсутствует. 4 Перед выполнением вызова [RequestIntegrityToken][request-integrity-token] вызовите действие [PrepareIntegrityToken][prepare-token].
kSdkRuntimeUpdateRequired Необходимо обновить SDK Play for Native. 8 Убедитесь, что клиент Google Play Services на устройстве обновлен и вы используете последнюю версию Play for Native PC SDK.

Протестируйте различные ответы API Play Integrity в своем приложении.

Вы можете создавать тесты для оценки того, как API Play Integrity взаимодействует с вашим приложением.

  1. Создайте группу Google (или столько, сколько пожелаете) с адресами электронной почты пользователей. Вы можете выбрать, какие результаты проверки целостности или коды ошибок должны получать эти пользователи в вашем приложении с серверов Google Play. Это позволит вам протестировать, как ваше приложение реагирует на все возможные ответы и ошибки.

  2. Создайте заявку здесь и сообщите, какая группа Google получит какой ответ API. Каждой группе назначен один из следующих вариантов:

    Вердикт по лицензированию Pass Вердикт по делу о невыполнении лицензионных обязательств Невозможно оценить вердикт по вопросу лицензирования.
    Прохождение проверки целостности устройства ALLOWLIST_CONFIG_MEETS_PC_INTEGRITY_LICENSED ALLOWLIST_CONFIG_MEETS_PC_INTEGRITY_UNLICENSED ALLOWLIST_CONFIG_MEETS_PC_INTEGRITY_LICENSING_UNEVALUATED
    Сбой целостности устройства Н/Д Н/Д ALLOWLIST_CONFIG_NO_PC_INTEGRITY_LICENSING_UNEVALUATED
    Если проверка целостности устройства не пройдёт, решение о выдаче лицензии всегда будет «НЕ ПРОВЕРЕНО».

  3. Вы получите уведомление, как только запрос будет обработан и тестовые пользователи будут добавлены в список разрешенных для получения предопределенных результатов проверки целостности данных для тестирования.