इंटेग्रिटी के नतीजे

इस पेज पर, पूरी सुरक्षा के बारे में मिले नतीजे का विश्लेषण करने और उससे जुड़े काम करने का तरीका बताया गया है. स्टैंडर्ड या क्लासिक एपीआई अनुरोध करने पर, पूरी सुरक्षा की जांच का नतीजा एक ही फ़ॉर्मैट में मिलता है. साथ ही, इसमें एक जैसा कॉन्टेंट होता है. इंटिग्रिटी के नतीजे से, डिवाइसों, ऐप्लिकेशन, और खातों की पुष्टि की जानकारी मिलती है. आपके ऐप्लिकेशन का सर्वर, डिक्रिप्ट किए गए और पुष्टि किए गए नतीजे में मौजूद पेलोड का इस्तेमाल कर सकता है. इससे यह तय किया जा सकता है कि आपके ऐप्लिकेशन में किसी खास कार्रवाई या अनुरोध को कैसे पूरा किया जाए.

पूरी सुरक्षा की जांच का नतीजा दिखाने का फ़ॉर्मैट

पेलोड, सादा टेक्स्ट JSON होता है. इसमें डेवलपर की दी गई जानकारी के साथ-साथ, पूरी सुरक्षा के सिग्नल भी शामिल होते हैं.

पेलोड का सामान्य स्ट्रक्चर इस तरह है:

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

आपको सबसे पहले यह देखना होगा कि requestDetails फ़ील्ड में मौजूद वैल्यू, मूल अनुरोध की वैल्यू से मैच करती हैं या नहीं. इसके बाद ही, कॉन्टेंट के भरोसेमंद होने के हर फ़ैसले की जांच करें. यहां दिए गए सेक्शन में, हर फ़ील्ड के बारे में ज़्यादा जानकारी दी गई है.

अनुरोध की जानकारी वाला फ़ील्ड

requestDetails फ़ील्ड में अनुरोध के बारे में जानकारी होती है. इसमें, स्टैंडर्ड अनुरोधों के लिए requestHash में डेवलपर की दी गई जानकारी और क्लासिक अनुरोधों के लिए nonce शामिल है.

स्टैंडर्ड एपीआई अनुरोधों के लिए:

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"
  // Request hash provided by the developer.
  requestHash: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the integrity token
  // was requested.
  timestampMillis: "1675655009345"
}

ये वैल्यू, मूल अनुरोध की वैल्यू से मेल खानी चाहिए. इसलिए, JSON पेलोड के requestDetails हिस्से की पुष्टि करें. इसके लिए, पक्का करें कि requestPackageName और requestHash, मूल अनुरोध में भेजे गए डेटा से मेल खाते हों. इसकी जानकारी, नीचे दिए गए कोड स्निपेट में दी गई है:

Kotlin

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val requestHash = requestDetails.getString("requestHash")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Java

RequestDetails requestDetails =
    decodeIntegrityTokenResponse
    .getTokenPayloadExternal()
    .getRequestDetails();
String requestPackageName = requestDetails.getRequestPackageName();
String requestHash = requestDetails.getRequestHash();
long timestampMillis = requestDetails.getTimestampMillis();
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request.
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

क्लासिक एपीआई अनुरोधों के लिए:

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 URL-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"
}

ये वैल्यू, मूल अनुरोध की वैल्यू से मेल खानी चाहिए. इसलिए, JSON पेलोड के requestDetails हिस्से की पुष्टि करें. इसके लिए, पक्का करें कि requestPackageName और nonce, मूल अनुरोध में भेजे गए डेटा से मेल खाते हों. इसकी जानकारी, यहां दिए गए कोड स्निपेट में दी गई है:

Kotlin

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val nonce = requestDetails.getString("nonce")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Java

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

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

ऐप्लिकेशन इंटिग्रिटी फ़ील्ड

appIntegrity फ़ील्ड में पैकेज से जुड़ी जानकारी होती है.

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 (base64-encoded URL-safe).
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  certificateSha256Digest: ["6a6a1474b5cbbb2b1aa57e0bc3"]
  // The version of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  versionCode: "42"
}

appRecognitionVerdict में ये वैल्यू हो सकती हैं:

PLAY_RECOGNIZED
ऐप्लिकेशन और सर्टिफ़िकेट, उन वर्शन से मेल खाते हैं जिन्हें Google Play ने उपलब्ध कराया है.
UNRECOGNIZED_VERSION
सर्टिफ़िकेट या पैकेज का नाम, Google Play के रिकॉर्ड से मेल नहीं खाता है.
UNEVALUATED
ऐप्लिकेशन इंटिग्रिटी की जांच नहीं की गई. कोई ज़रूरी शर्त पूरी नहीं हुई, जैसे कि डिवाइस भरोसेमंद नहीं है.

यह पक्का करने के लिए कि टोकन आपके बनाए गए ऐप्लिकेशन से जनरेट किया गया है, पुष्टि करें कि ऐप्लिकेशन की पूरी जानकारी सही है. इसकी जानकारी, नीचे दिए गए कोड स्निपेट में दी गई है:

Kotlin

val appIntegrity = JSONObject(payload).getJSONObject("appIntegrity")
val appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict")

if (appRecognitionVerdict == "PLAY_RECOGNIZED") {
    // Looks good!
}

Java

JSONObject appIntegrity =
    new JSONObject(payload).getJSONObject("appIntegrity");
String appRecognitionVerdict =
    appIntegrity.getString("appRecognitionVerdict");

if (appRecognitionVerdict.equals("PLAY_RECOGNIZED")) {
    // Looks good!
}

ऐप्लिकेशन के पैकेज का नाम, ऐप्लिकेशन का वर्शन, और ऐप्लिकेशन के सर्टिफ़िकेट की जानकारी मैन्युअल तरीके से भी देखी जा सकती है.

डिवाइस इंटिग्रिटी फ़ील्ड

deviceIntegrity फ़ील्ड में एक वैल्यू, deviceRecognitionVerdict हो सकती है. इसमें एक या उससे ज़्यादा लेबल होते हैं, जिनसे पता चलता है कि कोई डिवाइस, ऐप्लिकेशन इंटिग्रिटी को कितनी अच्छी तरह लागू कर सकता है. अगर कोई डिवाइस किसी भी लेबल की ज़रूरी शर्तें पूरी नहीं करता है, तो deviceIntegrity फ़ील्ड खाली होता है.

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

डिफ़ॉल्ट रूप से, deviceRecognitionVerdict में ये शामिल हो सकते हैं:

MEETS_DEVICE_INTEGRITY
ऐप्लिकेशन, Google Play services के साथ काम करने वाले Android डिवाइस पर चल रहा हो. डिवाइस की जांच में यह पता चला है कि इस पर सिस्टम को पूरी सुरक्षा मिलती है. साथ ही, यह Android के साथ काम करने की ज़रूरी शर्तों के मुताबिक है.
खाली (वैल्यू के तौर पर कोई वैल्यू नहीं दी गई है)
ऐप्लिकेशन किसी ऐसे डिवाइस पर चल रहा है जिस पर हमले (जैसे कि एपीआई हुकिंग) या सिस्टम से छेड़छाड़ (जैसे कि रूट किया गया) के संकेत मिले हैं. ऐसा भी हो सकता है कि ऐप्लिकेशन किसी फ़िज़िकल डिवाइस पर न चल रहा हो. उदाहरण के लिए, किसी ऐसे एम्युलेटर पर चल रहा हो जिसमें पूरी सुरक्षा देने वाला Google Play Integrity मौजूद नहीं है.

यह पक्का करने के लिए कि टोकन किसी भरोसेमंद डिवाइस से आया है, पुष्टि करें कि deviceRecognitionVerdict वैसा ही है जैसा यहां दिए गए कोड स्निपेट में दिखाया गया है:

Kotlin

val deviceIntegrity =
    JSONObject(payload).getJSONObject("deviceIntegrity")
val deviceRecognitionVerdict =
    if (deviceIntegrity.has("deviceRecognitionVerdict")) {
        deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    } else {
        ""
    }

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

Java

JSONObject deviceIntegrity =
    new JSONObject(payload).getJSONObject("deviceIntegrity");
String deviceRecognitionVerdict =
    deviceIntegrity.has("deviceRecognitionVerdict")
    ? deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    : "";

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

अगर आपको टेस्टिंग डिवाइस को डिवाइस इंटिग्रिटी की ज़रूरी शर्तें पूरी करने में समस्या आ रही है, तो पक्का करें कि डिवाइस पर फ़ैक्ट्री ROM इंस्टॉल हो. उदाहरण के लिए, डिवाइस को रीसेट करके. साथ ही, यह भी पक्का करें कि बूटलोडर लॉक हो. Play Console में Play Integrity API टेस्ट भी बनाए जा सकते हैं.

डिवाइस के लेबल, जो शर्तों के हिसाब से दिखते हैं

अगर आपका ऐप्लिकेशन पीसी के लिए Google Play Games पर रिलीज़ किया जा रहा है, तो deviceRecognitionVerdict में यह लेबल भी शामिल हो सकता है:

MEETS_VIRTUAL_INTEGRITY
ऐप्लिकेशन, Android पर काम करने वाले ऐसे एमुलेटर पर चल रहा है जिसमें Google Play services मौजूद है. एम्युलेटर की जांच से यह पता चला है कि इस पर सिस्टम को पूरी सुरक्षा मिलती है. साथ ही, यह Android के साथ काम करने की ज़रूरी शर्तों के मुताबिक है.

डिवाइस की जानकारी (ज़रूरी नहीं)

अगर आपने पूरी सुरक्षा देने की सुविधा की जांच के नतीजे में, ज़्यादा लेबल पाने के लिए ऑप्ट इन किया है, तो deviceRecognitionVerdict में ये अतिरिक्त लेबल शामिल हो सकते हैं:

MEETS_BASIC_INTEGRITY
यह ऐप्लिकेशन एक ऐसे डिवाइस पर चल रहा है जिस पर सिस्टम को बुनियादी स्तर की पूरी सुरक्षा मिलती है. हो सकता है कि डिवाइस, Android के साथ काम करने की ज़रूरी शर्तों को पूरा न करता हो और उसे Google Play की सेवाएं चलाने के लिए मंज़ूरी न मिली हो. उदाहरण के लिए, हो सकता है कि डिवाइस पर Android का कोई ऐसा वर्शन चल रहा हो जिसे Google Play की मंज़ूरी न मिली हो. इसके अलावा, यह भी हो सकता है कि उसमें अनलॉक किया गया बूटलोडर हो या मैन्युफ़ैक्चरर ने उसे सर्टिफ़िकेट न दिया हो.
MEETS_STRONG_INTEGRITY
यह ऐप्लिकेशन, Android डिवाइस पर चल रहा है. साथ ही, उसमें Google Play services की सुविधाएं भी मौजूद हैं. इससे, सिस्टम को मज़बूत स्तर की पूरी सुरक्षा देने की गारंटी मिलती है. उदाहरण के लिए, हार्डवेयर-बैक्ड बूट इंटिग्रिटी का सबूत. डिवाइस की जांच में यह पता चला है कि इस पर सिस्टम को पूरी सुरक्षा मिलती है. साथ ही, यह Android के साथ काम करने की ज़रूरी शर्तों के मुताबिक है.

अगर किसी डिवाइस के लिए, हर लेबल की शर्तें पूरी होती हैं, तो डिवाइस की पूरी सुरक्षा देने की सुविधा के नतीजे में, एक ही डिवाइस के लिए कई डिवाइस लेबल दिखेंगे.

डिवाइस पर हाल ही में की गई गतिविधि

आपके पास डिवाइस से हाल ही में की गई गतिविधि की जानकारी पाने की सुविधा के लिए ऑप्ट-इन करने का विकल्प भी है. इससे आपको यह पता चलता है कि आपके ऐप्लिकेशन ने पिछले एक घंटे में किसी खास डिवाइस पर इंटिग्रिटी टोकन के लिए कितनी बार अनुरोध किया है. डिवाइस से हाल ही में की गई गतिविधि का इस्तेमाल करके, अपने ऐप्लिकेशन को ऐसे डिवाइसों से बचाया जा सकता है जो अचानक से ज़्यादा गतिविधि करते हैं. ये डिवाइस, किसी हमले का संकेत हो सकते हैं. आपके पास यह तय करने का विकल्प होता है कि डिवाइस पर की गई हाल की गतिविधि के हर लेवल पर कितना भरोसा किया जाए. यह इस बात पर निर्भर करता है कि आपके हिसाब से, किसी सामान्य डिवाइस पर इंस्टॉल किए गए आपके ऐप्लिकेशन को हर घंटे इंटिग्रिटी टोकन के लिए कितनी बार अनुरोध करना चाहिए.

recentDeviceActivity पाने के लिए ऑप्ट-इन करने पर, deviceIntegrity फ़ील्ड में दो वैल्यू होंगी:

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

deviceActivityLevel की परिभाषाएं, मोड के हिसाब से अलग-अलग होती हैं. साथ ही, इनमें से कोई एक वैल्यू हो सकती है:

डिवाइस पर हाल ही में की गई गतिविधि का लेवल हर ऐप्लिकेशन के लिए, इस डिवाइस पर पिछले एक घंटे में किए गए स्टैंडर्ड एपीआई इंटिग्रिटी टोकन के अनुरोध हर ऐप्लिकेशन के लिए, इस डिवाइस पर पिछले एक घंटे में किए गए क्लासिक एपीआई इंटिग्रिटी टोकन के अनुरोध
LEVEL_1 (सबसे कम) 10 या कम 5 या इससे कम
LEVEL_2 11 से 25 के बीच 6 से 10
LEVEL_3 26 से 50 के बीच 11 से 15 के बीच
LEVEL_4 (सबसे ज़्यादा) 50 से ज़्यादा 15 से ज़्यादा
UNEVALUATED डिवाइस पर हाल ही में की गई गतिविधि का आकलन नहीं किया गया. ऐसा इन वजहों से हो सकता है:
  • डिवाइस भरोसेमंद नहीं है.
  • डिवाइस पर इंस्टॉल किए गए आपके ऐप्लिकेशन के वर्शन की जानकारी Google Play को नहीं है.
  • डिवाइस में तकनीकी समस्याएं.

डिवाइस की विशेषताएं

आपके पास डिवाइस एट्रिब्यूट के लिए भी ऑप्ट-इन करने का विकल्प होता है. इससे, डिवाइस पर चल रहे Android OS के Android SDK टूल के वर्शन के बारे में पता चलता है. आने वाले समय में, इसे डिवाइस के अन्य एट्रिब्यूट के साथ भी जोड़ा जा सकता है.

SDK टूल के वर्शन की वैल्यू, Android SDK टूल के वर्शन का नंबर होता है. इसे Build.VERSION_CODES में बताया गया है. अगर कोई ज़रूरी शर्त पूरी नहीं की गई है, तो SDK के वर्शन की जांच नहीं की जाती. इस मामले में, sdkVersion फ़ील्ड सेट नहीं है. इसलिए, deviceAttributes फ़ील्ड खाली है. ऐसा इन वजहों से हो सकता है:

  • डिवाइस भरोसेमंद नहीं है.
  • डिवाइस पर इंस्टॉल किए गए आपके ऐप्लिकेशन के वर्शन की जानकारी Google Play को नहीं है.
  • डिवाइस में तकनीकी समस्याएं थीं.

deviceAttributes पाने के लिए ऑप्ट इन करने पर, deviceIntegrity फ़ील्ड में यह अतिरिक्त फ़ील्ड दिखेगा:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  deviceAttributes: {
    // 33 is one possible value, which represents Android 13 (Tiramisu).
    sdkVersion: 33
  }
}

अगर SDK टूल के वर्शन का आकलन नहीं किया जाता है, तो deviceAttributes फ़ील्ड को इस तरह सेट किया जाएगा:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  deviceAttributes: {}  // sdkVersion field is not set.
}

खाते की जानकारी वाला फ़ील्ड

accountDetails फ़ील्ड में एक वैल्यू, appLicensingVerdict होती है. यह वैल्यू, डिवाइस पर साइन इन किए गए उपयोगकर्ता खाते के लिए, ऐप्लिकेशन के Google Play लाइसेंस की स्थिति दिखाती है. अगर उपयोगकर्ता खाते के पास ऐप्लिकेशन का Play लाइसेंस है, तो इसका मतलब है कि उसने ऐप्लिकेशन को Google Play से डाउनलोड किया है या खरीदा है.

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

appLicensingVerdict में इनमें से कोई एक वैल्यू हो सकती है:

LICENSED
उपयोगकर्ता के पास ऐप्लिकेशन का एनटाइटलमेंट है. दूसरे शब्दों में, उपयोगकर्ता ने अपने डिवाइस पर Google Play से आपका ऐप्लिकेशन इंस्टॉल किया या अपडेट किया है.
UNLICENSED
उपयोगकर्ता के पास ऐप्लिकेशन का एनटाइटलमेंट नहीं है. उदाहरण के लिए, ऐसा तब होता है, जब उपयोगकर्ता आपके ऐप्लिकेशन को अलग से लोड करता है या उसे Google Play से डाउनलोड नहीं करता. इस समस्या को ठीक करने के लिए, उपयोगकर्ताओं को GET_LICENSED डायलॉग दिखाया जा सकता है.
UNEVALUATED

लाइसेंस से जुड़ी जानकारी की जांच नहीं की गई, क्योंकि एक ज़रूरी शर्त पूरी नहीं हुई.

ऐसा कई वजहों से हो सकता है. इनमें ये वजहें शामिल हैं:

  • डिवाइस भरोसेमंद नहीं है.
  • डिवाइस पर इंस्टॉल किए गए आपके ऐप्लिकेशन के वर्शन की जानकारी Google Play को नहीं है.
  • उपयोगकर्ता ने Google Play में साइन इन नहीं किया है.

यह देखने के लिए कि उपयोगकर्ता के पास आपके ऐप्लिकेशन के लिए ऐप्लिकेशन एनटाइटलमेंट है या नहीं, पुष्टि करें कि appLicensingVerdict वैसा ही है जैसा यहां दिए गए कोड स्निपेट में दिखाया गया है:

Kotlin

val accountDetails = JSONObject(payload).getJSONObject("accountDetails")
val appLicensingVerdict = accountDetails.getString("appLicensingVerdict")

if (appLicensingVerdict == "LICENSED") {
    // Looks good!
}

Java

JSONObject accountDetails =
    new JSONObject(payload).getJSONObject("accountDetails");
String appLicensingVerdict = accountDetails.getString("appLicensingVerdict");

if (appLicensingVerdict.equals("LICENSED")) {
    // Looks good!
}

एनवायरमेंट की जानकारी वाला फ़ील्ड

आपके पास एनवायरमेंट के बारे में ज़्यादा सिग्नल के लिए ऑप्ट-इन करने का विकल्प भी है. ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम की सूचना पाने की सुविधा, आपके ऐप्लिकेशन को यह जानकारी देती है कि क्या आपके डिवाइस में ऐसे अन्य ऐप्लिकेशन चल रहे हैं जिनका इस्तेमाल स्क्रीन कैप्चर करने, ओवरले दिखाने या डिवाइस को कंट्रोल करने के लिए किया जा सकता है. Play Protect के नतीजे से आपको पता चलता है कि डिवाइस पर Google Play Protect की सुविधा चालू है या नहीं. साथ ही, यह भी पता चलता है कि उसे कोई मैलवेयर मिला है या नहीं.

अगर आपने Google Play Console में, ऐप्लिकेशन के ऐक्सेस से जुड़े जोखिम के नतीजे या Play Protect के नतीजे के लिए ऑप्ट-इन किया है, तो आपके एपीआई रिस्पॉन्स में environmentDetails फ़ील्ड शामिल होगा. environmentDetails फ़ील्ड में दो वैल्यू, appAccessRiskVerdict और playProtectVerdict हो सकती हैं.

ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम की जानकारी

चालू होने के बाद, Play Integrity API के पेलोड में मौजूद environmentDetails फ़ील्ड में, ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम का नया नतीजा दिखेगा.

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: {
      appAccessRiskVerdict: {
          // This field contains one or more responses, for example the following.
          appsDetected: ["KNOWN_INSTALLED", "UNKNOWN_INSTALLED", "UNKNOWN_CAPTURING"]
      }
 }
}

अगर ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम का आकलन किया गया था, तो appAccessRiskVerdict में एक या एक से ज़्यादा जवाबों वाला फ़ील्ड appsDetected होता है. इन जवाबों को, इन दो ग्रुप में बांटा गया है. यह बांटने का आधार, ऐप्लिकेशन इंस्टॉल करने के सोर्स पर निर्भर करता है:

  • Play या सिस्टम ऐप्लिकेशन: ऐसे ऐप्लिकेशन जिन्हें Google Play से इंस्टॉल किया गया है या डिवाइस बनाने वाली कंपनी ने डिवाइस के सिस्टम पार्टीशन (FLAG_SYSTEM से पहचाने जाते हैं) में पहले से लोड किया है. ऐसे ऐप्लिकेशन के जवाबों के आगे KNOWN_ लगा होता है.

  • अन्य ऐप्लिकेशन: ऐसे ऐप्लिकेशन जिन्हें Google Play से इंस्टॉल नहीं किया गया है. इसमें, डिवाइस बनाने वाली कंपनी के सिस्टम पार्टीशन में पहले से लोड किए गए ऐप्लिकेशन शामिल नहीं हैं. ऐसे ऐप्लिकेशन के लिए मिले जवाबों के आगे UNKNOWN_ लगा होता है.

इनमें से कोई जवाब मिल सकता है:

KNOWN_INSTALLED, UNKNOWN_INSTALLED
ऐसे ऐप्लिकेशन इंस्टॉल हैं जो इंस्टॉल करने के सोर्स से मेल खाते हैं.
KNOWN_CAPTURING, UNKNOWN_CAPTURING
ऐसे ऐप्लिकेशन चल रहे हैं जिनके पास ऐसी अनुमतियां हैं जिनका इस्तेमाल, आपके ऐप्लिकेशन के चलने के दौरान स्क्रीन देखने के लिए किया जा सकता है. इसमें, डिवाइस पर चल रही ऐसी सभी ऐक्सेसबिलिटी सेवाएं शामिल नहीं हैं जिनकी पुष्टि हो चुकी है और जिनके बारे में Google Play को पता है.
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
ऐसे ऐप्लिकेशन चल रहे हैं जिनके पास ऐसी अनुमतियां हैं जिनका इस्तेमाल डिवाइस को कंट्रोल करने और आपके ऐप्लिकेशन में इनपुट को सीधे तौर पर कंट्रोल करने के लिए किया जा सकता है. साथ ही, इनका इस्तेमाल आपके ऐप्लिकेशन के इनपुट और आउटपुट को कैप्चर करने के लिए भी किया जा सकता है. हालांकि, इसमें ऐसी सभी ऐक्सेसबिलिटी सेवाएं शामिल नहीं हैं जिनकी पुष्टि हो चुकी है और जो डिवाइस पर Google Play के ज़रिए चल रही हैं.
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
ऐसे ऐप्लिकेशन चल रहे हैं जिनमें ऐसी अनुमतियां चालू हैं जिनका इस्तेमाल आपके ऐप्लिकेशन पर ओवरले दिखाने के लिए किया जा सकता है. इसमें, डिवाइस पर चल रही ऐसी सभी सुलभता सेवाएं शामिल नहीं हैं जिनकी पुष्टि Google Play ने की है.
खाली (वैल्यू के तौर पर कोई वैल्यू नहीं दी गई है)

अगर कोई ज़रूरी शर्त पूरी नहीं की गई है, तो ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम का आकलन नहीं किया जाता. इस मामले में, appAccessRiskVerdict फ़ील्ड खाली है. ऐसा कई वजहों से हो सकता है. इनमें ये वजहें शामिल हैं:

  • डिवाइस भरोसेमंद नहीं है.
  • डिवाइस फ़ॉर्म फ़ैक्टर, फ़ोन, टैबलेट या फ़ोल्ड होने वाला डिवाइस न हो.
  • डिवाइस पर Android 6 (एपीआई लेवल 23) या उसके बाद का वर्शन नहीं चल रहा है.
  • डिवाइस पर इंस्टॉल किए गए आपके ऐप्लिकेशन के वर्शन की जानकारी Google Play को नहीं है.
  • डिवाइस पर Google Play Store का वर्शन पुराना है.
  • सिर्फ़ गेम के लिए: उपयोगकर्ता के खाते में, गेम के लिए Play का लाइसेंस नहीं है.
  • verdictOptOut पैरामीटर के साथ स्टैंडर्ड अनुरोध का इस्तेमाल किया गया था.
  • स्टैंडर्ड अनुरोध के लिए, Play Integrity API लाइब्रेरी के ऐसे वर्शन का इस्तेमाल किया गया था जो अब तक स्टैंडर्ड अनुरोधों के लिए, ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम की सूचना देने की सुविधा के साथ काम नहीं करता.

ऐप्लिकेशन के ऐक्सेस से जुड़े जोखिम की चेतावनी में, उन ऐक्सेसबिलिटी सेवाओं को अपने-आप बाहर रखा जाता है जिनकी पुष्टि हो चुकी है और जिन्हें Google Play की ऐक्सेसबिलिटी की बेहतर समीक्षा के तहत रखा गया है. ये सेवाएं, डिवाइस पर किसी भी ऐप्लिकेशन स्टोर से इंस्टॉल की जाती हैं. "शामिल नहीं है" का मतलब है कि डिवाइस पर चल रही पुष्टि की गई सुलभता सेवाएं, ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम के फ़ैसले में, कैप्चर करने, कंट्रोल करने या ओवरले दिखाने का जवाब नहीं देंगी. अपने ऐक्सेसबिलिटी ऐप्लिकेशन के लिए, Google Play पर ऐक्सेसबिलिटी की बेहतर समीक्षा का अनुरोध करने के लिए, उसे Google Play पर पब्लिश करें. साथ ही, पक्का करें कि आपके ऐप्लिकेशन के मेनिफ़ेस्ट में isAccessibilityTool फ़्लैग को 'सही' पर सेट किया गया हो या समीक्षा का अनुरोध करें.

यहां दी गई टेबल में, नतीजों के कुछ उदाहरण और उनका मतलब बताया गया है. हालांकि, इस टेबल में सभी संभावित नतीजे शामिल नहीं हैं:

ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम की जानकारी के जवाब का उदाहरण परिभाषा
appsDetected:
["KNOWN_INSTALLED"]
सिर्फ़ ऐसे ऐप्लिकेशन इंस्टॉल किए गए हों जिन्हें Google Play ने मंज़ूरी दी हो या डिवाइस बनाने वाली कंपनी ने सिस्टम पार्टीशन में पहले से लोड किया हो.
ऐसे कोई भी ऐप्लिकेशन न चल रहा हो जिसकी वजह से स्क्रीन कैप्चर करने, कंट्रोल करने या ओवरले करने से जुड़े फ़ैसले मिलें.
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
Google Play से इंस्टॉल किए गए ऐप्लिकेशन या डिवाइस बनाने वाली कंपनी की ओर से सिस्टम पार्टीशन में पहले से लोड किए गए ऐप्लिकेशन.
ऐसे अन्य ऐप्लिकेशन चल रहे हैं जिनके पास स्क्रीन देखने या अन्य इनपुट और आउटपुट कैप्चर करने के लिए अनुमतियां चालू हैं.
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
Play या सिस्टम में ऐसी अनुमतियां चालू हैं जिनका इस्तेमाल, स्क्रीन देखने या अन्य इनपुट और आउटपुट कैप्चर करने के लिए किया जा सकता है.
ऐसे अन्य ऐप्लिकेशन भी चल रहे हैं जिनके पास ऐसी अनुमतियां चालू हैं जिनका इस्तेमाल करके, डिवाइस को कंट्रोल किया जा सकता है. साथ ही, आपके ऐप्लिकेशन में इनपुट को सीधे तौर पर कंट्रोल किया जा सकता है.
appAccessRiskVerdict: {} ऐप्लिकेशन के ऐक्सेस से जुड़े जोखिम का आकलन नहीं किया गया, क्योंकि एक ज़रूरी शर्त पूरी नहीं हुई. उदाहरण के लिए, डिवाइस भरोसेमंद नहीं था.

जोखिम के लेवल के आधार पर, यह तय किया जा सकता है कि आगे बढ़ने के लिए, नतीजों के किस कॉम्बिनेशन को स्वीकार किया जाए और किन नतीजों के आधार पर कार्रवाई की जाए. यहां दिए गए कोड स्निपेट में, इस बात की पुष्टि करने का उदाहरण दिया गया है कि कोई ऐसा ऐप्लिकेशन नहीं चल रहा है जो स्क्रीन कैप्चर कर सकता है या आपके ऐप्लिकेशन को कंट्रोल कर सकता है:

Kotlin

val environmentDetails =
    JSONObject(payload).getJSONObject("environmentDetails")
val appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict")

if (appAccessRiskVerdict.has("appsDetected")) {
    val appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}

Java

JSONObject environmentDetails =
    new JSONObject(payload).getJSONObject("environmentDetails");
JSONObject appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict");

if (appAccessRiskVerdict.has("appsDetected")) {
    String appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}
ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम की जानकारी को ठीक करना

जोखिम के लेवल के आधार पर, यह तय किया जा सकता है कि उपयोगकर्ता को कोई अनुरोध या कार्रवाई करने से पहले, ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम के किन नतीजों पर कार्रवाई करनी है. ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम की जांच के नतीजे देखने के बाद, उपयोगकर्ता को Google Play के कुछ प्रॉम्प्ट दिखाए जा सकते हैं. हालांकि, ऐसा करना ज़रूरी नहीं है. उपयोगकर्ता से उन ऐप्लिकेशन को बंद करने के लिए कहा जा सकता है जिनकी वजह से, ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम की जांच के नतीजे में यह पता चलता है कि उन ऐप्लिकेशन में जोखिम है. इसके लिए, CLOSE_UNKNOWN_ACCESS_RISK दिखाया जा सकता है. इसके अलावा, उपयोगकर्ता से उन सभी ऐप्लिकेशन को बंद करने के लिए कहा जा सकता है जिनकी वजह से, ऐप्लिकेशन को ऐक्सेस करने से जुड़े जोखिम की जांच के नतीजे में यह पता चलता है कि उन ऐप्लिकेशन में जोखिम है. इसके लिए, CLOSE_ALL_ACCESS_RISK दिखाया जा सकता है.

Play Protect का फ़ैसला

इस सुविधा के चालू होने के बाद, Play Integrity API के पेलोड में मौजूद environmentDetails फ़ील्ड में, Play Protect का नतीजा दिखेगा:

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

playProtectVerdict में इनमें से कोई एक वैल्यू हो सकती है:

NO_ISSUES
Play Protect चालू है और उसे डिवाइस पर ऐप्लिकेशन से जुड़ी कोई समस्या नहीं मिली.
NO_DATA
Play Protect की सुविधा चालू है, लेकिन अभी तक कोई स्कैन नहीं किया गया है. हो सकता है कि डिवाइस या Play Store ऐप्लिकेशन को हाल ही में रीसेट किया गया हो.
POSSIBLE_RISK
Play Protect की सुविधा बंद है.
MEDIUM_RISK
Play Protect की सुविधा चालू है और उसे डिवाइस पर, नुकसान पहुंचाने वाले ऐप्लिकेशन मिले हैं.
HIGH_RISK
Play Protect की सुविधा चालू है और उसे डिवाइस पर इंस्टॉल किए गए खतरनाक ऐप्लिकेशन मिले हैं.
UNEVALUATED

Play Protect के फ़ैसले का आकलन नहीं किया गया.

ऐसा कई वजहों से हो सकता है. इनमें ये वजहें शामिल हैं:

  • डिवाइस भरोसेमंद नहीं है.
  • सिर्फ़ गेम के लिए: उपयोगकर्ता के खाते में, गेम के लिए Play का लाइसेंस नहीं है.

Play Protect के फ़ैसले का इस्तेमाल करने के बारे में दिशा-निर्देश

आपके ऐप्लिकेशन का बैकएंड सर्वर यह तय कर सकता है कि नतीजे के आधार पर, आपको किस तरह की कार्रवाई करनी है. यह तय करने के लिए, आपके जोखिम को स्वीकार करने की सीमा का ध्यान रखा जाता है. यहां कुछ सुझाव और उपयोगकर्ता की संभावित कार्रवाइयां दी गई हैं:

NO_ISSUES
Play Protect चालू है और उसे कोई समस्या नहीं मिली है. इसलिए, उपयोगकर्ता को कुछ करने की ज़रूरत नहीं है.
POSSIBLE_RISK और NO_DATA
इन नतीजों के मिलने पर, उपयोगकर्ता से यह जांच करने के लिए कहें कि Play Protect चालू है या नहीं और उसने स्कैन किया है या नहीं. NO_DATA सिर्फ़ कुछ ही मामलों में दिखना चाहिए.
MEDIUM_RISK और HIGH_RISK
जोखिम को स्वीकार करने की आपकी क्षमता के आधार पर, उपयोगकर्ता से Play Protect को लॉन्च करने और Play Protect की चेतावनियों पर कार्रवाई करने के लिए कहा जा सकता है. अगर उपयोगकर्ता इन ज़रूरी शर्तों को पूरा नहीं कर पाता है, तो उसे सर्वर ऐक्शन से ब्लॉक किया जा सकता है.