התכונה Play Integrity למחשב עוזרת לכם לוודא שאירועים במשחק ובקשות מהשרת מגיעים ממופע מקורי של Google Play Games במחשב במכשיר מחשב מקורי. באמצעות זיהוי של מכשירים שעלולים להיות מסוכנים ואמולטורים לא מוכרים, השרת העורפי של המשחק יכול להגיב בפעולות מתאימות כדי למנוע רמאות, גישה לא מורשית, תנועה שמקורה בתרמית וניצול לרעה.
דרישות מוקדמות
- משלימים את הגדרת ה-SDK.
- כדאי לעיין בשיקולי האבטחה של Integrity API.
- חשוב לקרוא ולהבין את התנאים וההגבלות של Integrity API ואת המידע על הטיפול בנתונים.
- במסוף Google Cloud, יוצרים פרויקט Cloud או בוחרים פרויקט Cloud קיים שרוצים להשתמש בו עם Play Integrity למחשב. עוברים אל APIs & services ומפעילים את Google Play Integrity API.
- אם אתם צופים שתשלחו יותר מ-10,000 בקשות ביום ל-Play Integrity למחשב, כדאי לבקש להגדיל את המקסימום היומי.
שלב 1: מחליטים איך להשתמש ב-Play Integrity במחשב במשחק
קובעים מתי תתבצע קריאה ל-Play Integrity למחשב כדי לקבל קביעת תקינות לגבי הסביבה. לדוגמה, אפשר לבקש פסיקה כשהמשחק נפתח, כששחקן נכנס לחשבון או כששחקן מצטרף למשחק מרובה משתתפים. לאחר מכן מחליטים איך לטפל בתגובות שונות לקביעת תקינות. לדוגמה, אפשר:
- לאסוף את התגובה בלי לבצע פעולות אכיפה, ולנתח את הנתונים באופן פנימי כדי להבין אם מדובר באות שימושי לזיהוי התנהלות פוגעת.
- אוספים את התגובה ומטמיעים לוגיקה בשרת העורפי כדי לאפשר למכשירים שעברו את בדיקות היושרה לשחק במשחק כרגיל, תוך הצגת אתגר או דחיית גישה לתנועה שמגיעה מסביבות חשודות.
- אוספים את התגובה ומטמיעים לוגיקה בשרת העורפי כדי להתאים בין שחקנים במכשירים שעוברים את בדיקות התקינות, וגם להתאים בין תנועה שמגיעה מסביבות חשודות.
שלב 2: מבקשים טוקנים של תקינות במשחק
חימום של Play Integrity למחשב
הכנה (או 'חימום') של 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 כדי לצמצם את הסיכון להתקפות של שיבוש. לדוגמה, יכול להיות שתרצו לדווח על הניקוד של השחקן לשרת העורפי של המשחק, והשרת ירצה לוודא ששרת proxy לא שינה את הניקוד הזה. התכונה 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: בשלב הבא, מפענחים ומאמתים את טוקני התקינות בשרת העורפי של המשחק
פענוח טוקן תקינות
אחרי שמבקשים קביעת תקינות, Play Integrity API מספק טוקן תגובה מוצפן. כדי לקבל את קביעות התקינות של המכשיר, צריך לפענח את טוקן התקינות בשרתים של Google:
- יוצרים חשבון שירות בפרויקט Google Cloud שמקושר לאפליקציה.
בשרת של האפליקציה, מאחזרים את אסימון הגישה מפרטי הכניסה של חשבון השירות באמצעות היקף ההרשאות playintegrity, ושולחים את הבקשה הבאה:
playintegrity.googleapis.com/v1/<var>PACKAGE_NAME</var>:decodePcIntegrityToken -d \ '{ "integrity_token": "<var>INTEGRITY_TOKEN</var>" }'
קוראים את תגובת ה-JSON.
המטען הייעודי (Payload) שמתקבל הוא טוקן טקסט פשוט שמכיל פסקי דין של יושרה ופרטים לצד מידע שסופק על ידי המפתח. אסימון שלמות מפוענח נראה כך:
{
"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
במטען הייעודי (payload) של 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 hooking) או לפריצה למערכת (למשל, המכשיר מריץ גרסה ששונתה של Google Desktop Services), או שהאפליקציה לא פועלת במכשיר פיזי (למשל, אמולטור שלא עובר את בדיקות התקינות של Google Play).
קביעות התקינות של פרטי החשבון
המאפיין appLicensingVerdict
יכול לקבל את הערכים הבאים:
LICENSED
- למשתמש יש הרשאה לאפליקציה. במילים אחרות, המשתמש התקין או עדכן את האפליקציה שלך מ-Google Play במכשיר שלו.
UNLICENSED
- למשתמש אין הרשאה לאפליקציה. זה קורה למשל כשהמשתמש מתקין את האפליקציה בשיטה חלופית, או לא מתקין אותה דרך Google Play.
UNEVALUATED
- לא בדקנו את פרטי הרישוי כי לא עמדת בדרישה נדרשת.
יכולות להיות לכך כמה סיבות, כולל הסיבות הבאות:
- המכשיר לא מספיק מהימן.
- גרסת האפליקציה שמותקנת במכשיר לא מוכרת ל-Google Play.
- המשתמש לא מחובר ל-Google Play.
שלב 5: טיפול בקודי שגיאה
אם המשחק שלכם שולח בקשה ל-Play Integrity למחשב והקריאה נכשלת, המשחק מקבל קוד שגיאה. השגיאות האלה יכולות לקרות מסיבות שונות, כמו בעיות סביבתיות (לדוגמה: חיבור רשת חלש), בעיות בשילוב של ה-API או פעילות זדונית והתקפות פעילות.
קודי שגיאה שאפשר לנסות לתקן
הסיבה לשגיאות האלה היא לפעמים תנאים זמניים, ולכן צריך לנסות שוב את הקריאה באמצעות אסטרטגיית השהיה מעריכית לפני ניסיון חוזר (exponential backoff).
IntegrityError | תיאור השגיאה | קוד השגיאה |
---|---|---|
kNetworkError |
בעיה בחיבור לרשת במכשיר. | 5 |
kTooManyRequests |
יותר מדי בקשות נשלחו מהמכשיר. | 6 |
kClientTransientError |
בעיה זמנית בצד הלקוח. | 7 |
כאן אפשר למצוא המלצות נוספות לגבי אסטרטגיות לניסיון חוזר.
קודי שגיאה שלא ניתן לנסות שוב
במקרים כאלה, סביר להניח שניסיונות חוזרים אוטומטיים לא יעזרו. עם זאת, ניסיון חוזר ידני עשוי לעזור אם המשתמש יטפל בתנאי שגרם לבעיה.
IntegrityError | תיאור השגיאה | קוד השגיאה | מה מומלץ לעשות? |
---|---|---|---|
kError |
שגיאה חמורה במהלך פעולת SDK. | 1 | לפני שמנסים שוב, צריך לאמת את ההטמעה של ממשק ה-API. |
kCloudProjectNumberIsInvalid |
מספר הפרויקט ב-Cloud לא תקין. | 2 | מוודאים שמספר הפרויקט בענן מוגדר בצורה נכונה במסוף Google Cloud, ושהבקשות נשלחות עם מספר הפרויקט הנכון בענן. |
kRequestHashTooLong |
בקשת הגיבוב (hash) ארוכה מדי. | 3 | הגיבובים (hash) של הבקשות שנוצרו ארוכים מדי. הם צריכים להיות קצרים מ-500 תווים. |
kNoValidPreparedTokenFound |
אין טוקן מוכן לפני שליחת בקשת הטוקן. | 4 | צריך להפעיל את הפעולה [PrepareIntegrityToken][prepare-token] לפני שמבצעים את הקריאה [RequestIntegrityToken][request-integrity-token]. |
kSdkRuntimeUpdateRequired |
נדרש עדכון ל-Play for Native SDK. | 8 | מוודאים שהלקוח של Google Play Services במכשיר עדכני ושהגרסה העדכנית של Play for Native PC SDK מותקנת. |
בדיקת תגובות שונות של Play Integrity API באפליקציה
אתם יכולים ליצור בדיקות כדי להעריך את האינטראקציה של Play Integrity API עם האפליקציה שלכם.
מגדירים קבוצת Google (או כמה שרוצים) עם כתובות אימייל של משתמשים. אתם יכולים לבחור את תוצאות הבדיקה של השלמות או את קוד השגיאה שהמשתמשים האלה צריכים לקבל באפליקציה מהשרתים של Google Play. כך תוכלו לבדוק איך האפליקציה שלכם מגיבה לכל התשובות והשגיאות האפשריות.
כאן אפשר ליצור כרטיס ולדווח איזו קבוצת Google תקבל איזו תגובת API. לכל קבוצה מוקצה אחד מהערכים הבאים:
קביעת תקינות הרישיון תוצאת הרישוי היא 'נכשל' לא ניתן להעריך את קביעת סטטוס הרישיון תקינות המכשיר 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
תישלח אליכם הודעה כשהבקשה תעובד והמשתמשים בבדיקה יתווספו לרשימת ההיתרים כדי לקבל את תוצאות הבדיקה המוגדרות מראש.