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

अगर आपको सिर्फ़ स्टैंडर्ड एपीआई अनुरोध करने हैं, जो ज़्यादातर डेवलपर के लिए सही होते हैं, तो सीधे भरोसेमंद होने के फ़ैसले पर जाएं. इस पेज पर, इंटिग्रिटी के नतीजों के लिए क्लासिक एपीआई अनुरोध करने के बारे में बताया गया है. ये अनुरोध, Android 4.4 (एपीआई लेवल 19) या इसके बाद के वर्शन पर किए जा सकते हैं.

ज़रूरी बातें

स्टैंडर्ड और क्लासिक अनुरोधों की तुलना करना

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

यहां दी गई टेबल में, दोनों तरह के अनुरोधों के बीच के मुख्य अंतर को हाइलाइट किया गया है:

स्टैंडर्ड एपीआई अनुरोध क्लासिक एपीआई अनुरोध
ज़रूरी शर्तें
Android SDK टूल का ज़रूरी वर्शन Android 5.0 (एपीआई लेवल 21) या इसके बाद का वर्शन Android 4.4 (एपीआई लेवल 19) या इसके बाद के वर्शन
Google Play की ज़रूरी शर्तें Google Play Store और Google Play services Google Play Store और Google Play services
इंटिग्रेशन की जानकारी
एपीआई को चालू करने के लिए कुछ समय लगता है ✔️ (कुछ सेकंड)
अनुरोध पूरा होने में लगने वाला सामान्य समय कुछ सौ मिलीसेकंड कुछ सेकंड
अनुरोध की संभावित फ़्रीक्वेंसी बार-बार (किसी कार्रवाई या अनुरोध के लिए, मांग पर जांच करना) कभी-कभी (सबसे ज़्यादा वैल्यू वाले कन्वर्ज़न ऐक्शन या सबसे संवेदनशील अनुरोधों के लिए एक बार जांच)
टाइम आउट की संख्या ज़्यादातर वार्म अप 10 सेकंड से कम समय में हो जाते हैं. हालांकि, इनमें सर्वर कॉल शामिल होता है. इसलिए, लंबे समय तक टाइम आउट करने का सुझाव दिया जाता है. उदाहरण के लिए, एक मिनट. फ़ैसले के अनुरोध, क्लाइंट-साइड पर होते हैं ज़्यादातर अनुरोध 10 सेकंड से कम समय में पूरे हो जाते हैं. हालांकि, इनमें सर्वर कॉल शामिल होता है. इसलिए, लंबे समय तक टाइम आउट होने की सुविधा इस्तेमाल करने का सुझाव दिया जाता है. उदाहरण के लिए, एक मिनट
भरोसेमंद होने की जांच का नतीजा देने वाला टोकन
इसमें डिवाइस, ऐप्लिकेशन, और खाते की जानकारी शामिल होती है ✔️ ✔️
टोकन को कैश मेमोरी में सेव करना Google Play की अपने-आप पूरी सुरक्षा देने की सुविधा के तहत, डिवाइस पर कैश मेमोरी को सुरक्षित रखा जाता है हम आपको इसका सुझाव नहीं देते हैं
Google Play सर्वर के ज़रिए टोकन को डिक्रिप्ट करना और उसकी पुष्टि करना ✔️ ✔️
सर्वर से सर्वर तक के अनुरोध को डिक्रिप्ट करने में लगने वाला सामान्य समय तीन-नौ की उपलब्धता के साथ 10 मिलीसेकंड तीन नाइन की उपलब्धता के साथ 10 मिलीसेकंड
सुरक्षित सर्वर एनवायरमेंट में, टोकन को स्थानीय तौर पर डिक्रिप्ट और पुष्टि करना ✔️
क्लाइंट-साइड पर टोकन को डिक्रिप्ट करना और उसकी पुष्टि करना
इंटिग्रिटी जांच के नतीजे के अपडेट होने की फ़्रीक्वेंसी Google Play की ओर से, कुछ हद तक अपने-आप कैश मेमोरी में सेव होने और रीफ़्रेश होने की सुविधा हर अनुरोध पर, सभी फ़ैसलों को फिर से कैलकुलेट किया जाता है
सीमाएं
हर ऐप्लिकेशन के लिए, हर दिन के अनुरोध डिफ़ॉल्ट रूप से 10,000 (इसे बढ़ाने का अनुरोध किया जा सकता है) डिफ़ॉल्ट रूप से 10,000 (इसे बढ़ाने का अनुरोध किया जा सकता है)
हर ऐप्लिकेशन इंस्टेंस से हर मिनट किए गए अनुरोध वार्म अप: हर मिनट में 5
इंटीग्रिटी टोकन: कोई सार्वजनिक सीमा तय नहीं है*
इंटीग्रिटी टोकन: हर मिनट में 5
सुरक्षा
डेटा में छेड़छाड़ और इस तरह के अन्य हमलों से बचाव करना requestHash फ़ील्ड का इस्तेमाल करना अनुरोध के डेटा के आधार पर, कॉन्टेंट बाइंडिंग के साथ nonce फ़ील्ड का इस्तेमाल करना
जवाबी और मिलते-जुलते हमलों से बचाव करना Google Play की ओर से अपने-आप जोखिम कम करने की सुविधा सर्वर साइड लॉजिक के साथ nonce फ़ील्ड का इस्तेमाल करना

* सभी अनुरोधों पर, ज़्यादा वैल्यू के लिए गैर-सार्वजनिक डिफ़ेंसिव सीमाएं लागू होती हैं. इनमें वे अनुरोध भी शामिल हैं जिन पर सार्वजनिक सीमाएं लागू नहीं होती हैं

क्लासिक अनुरोध कभी-कभी ही करें

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

नतीजों को कैश मेमोरी में सेव करने से बचें

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

क्लासिक अनुरोधों को सुरक्षित रखने के लिए, नॉन्स फ़ील्ड का इस्तेमाल करना

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

एक्स्पोनेंशियल बैकऑफ़ के साथ क्लासिक अनुरोधों को फिर से आज़माएं

डिवाइस की इंटिग्रिटी जांच के पूरा न होने की वजहें: इंटरनेट कनेक्शन ठीक न होना या डिवाइस पर बहुत ज़्यादा लोड होना. इस वजह से, भरोसेमंद डिवाइस के लिए भी लेबल जनरेट नहीं हो सकते. इन स्थितियों से बचने के लिए, एक्स्पोनेंशियल बैकऑफ़ के साथ फिर से कोशिश करने का विकल्प शामिल करें.

खास जानकारी

पहली इमेज. सीक्वेंस डायग्राम, जिसमें Play Integrity API के हाई-लेवल डिज़ाइन को दिखाया गया है.

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

  1. आपके ऐप्लिकेशन का सर्वर-साइड बैकएंड, क्लाइंट-साइड लॉजिक को एक यूनीक वैल्यू जनरेट करके भेजता है. बाकी चरणों में, इस लॉजिक को आपका "ऐप्लिकेशन" माना जाता है.
  2. आपका ऐप्लिकेशन, यूनीक वैल्यू और आपकी हाई-वैल्यू ऐक्शन के कॉन्टेंट से nonce बनाता है. इसके बाद, यह Play Integrity API को कॉल करता है और nonce को पास करता है.
  3. आपके ऐप्लिकेशन को Play Integrity API से, हस्ताक्षर किया गया और एन्क्रिप्ट (सुरक्षित) किया गया नतीजा मिलता है.
  4. आपका ऐप्लिकेशन, हस्ताक्षर किए गए और एन्क्रिप्ट (सुरक्षित) किए गए फ़ैसले को आपके ऐप्लिकेशन के बैकएंड पर भेजता है.
  5. आपके ऐप्लिकेशन का बैकएंड, फ़ैसले को Google Play के सर्वर पर भेजता है. Google Play सर्वर, नतीजे को डिक्रिप्ट और उसकी पुष्टि करता है. इसके बाद, नतीजे आपके ऐप्लिकेशन के बैकएंड को भेज दिए जाते हैं.
  6. आपके ऐप्लिकेशन का बैकएंड, टोकन पेलोड में मौजूद सिग्नल के आधार पर यह तय करता है कि आगे क्या करना है.
  7. आपके ऐप्लिकेशन का बैकएंड, फ़ैसले के नतीजों को आपके ऐप्लिकेशन पर भेजता है.

नॉन्स जनरेट करना

Play Integrity API की मदद से, अपने ऐप्लिकेशन में किसी कार्रवाई को सुरक्षित रखने के लिए, nonce फ़ील्ड का इस्तेमाल किया जा सकता है. इससे कुछ तरह के हमलों को कम किया जा सकता है. जैसे, पर्सन-इन-द-मिडल (पीआईटीएम) टेंपरिंग के हमले और रीप्ले के हमले. Play Integrity API, इस फ़ील्ड में सेट की गई वैल्यू को हस्ताक्षर किए गए इंटिग्रिटी रिस्पॉन्स में दिखाता है.

nonce फ़ील्ड में सेट की गई वैल्यू को सही तरीके से फ़ॉर्मैट किया जाना चाहिए:

  • String
  • यूआरएल के लिए सुरक्षित
  • Base64 कोड में बदला गया और रैप नहीं किया गया
  • कम से कम 16 वर्ण
  • ज़्यादा से ज़्यादा 500 वर्ण

Play Integrity API में nonce फ़ील्ड का इस्तेमाल करने के कुछ सामान्य तरीके यहां दिए गए हैं. nonce से बेहतर सुरक्षा पाने के लिए, यहां दिए गए तरीकों को एक साथ इस्तेमाल किया जा सकता है.

छेड़छाड़ से बचाने के लिए, अनुरोध हैश शामिल करें

अनुरोध के कॉन्टेंट में छेड़छाड़ से बचाने के लिए, क्लासिक एपीआई अनुरोध में nonce पैरामीटर का इस्तेमाल किया जा सकता है. इसका इस्तेमाल, स्टैंडर्ड एपीआई अनुरोध में requestHash पैरामीटर की तरह ही किया जाता है.

इंटिग्रिटी के नतीजे का अनुरोध करने पर:

  1. उपयोगकर्ता की कार्रवाई या सर्वर के अनुरोध से होने वाली सभी ज़रूरी अनुरोधों के पैरामीटर का डाइजेस्ट (जैसे, अनुरोध के स्टेबल सीरियलाइज़ेशन का SHA256) कंप्यूट करें.
  2. nonce फ़ील्ड को कंप्यूट किए गए डाइजेस्ट की वैल्यू पर सेट करने के लिए, setNonce का इस्तेमाल करें.

इंटिग्रिटी की जांच का नतीजा मिलने पर:

  1. इंटेग्रिटी टोकन को डिकोड करें और उसकी पुष्टि करें. साथ ही, nonce फ़ील्ड से डाइजेस्ट पाएं.
  2. अनुरोध का डाइजेस्ट उसी तरीके से कंप्यूट करें जिस तरीके से ऐप्लिकेशन में किया जाता है. उदाहरण के लिए, स्थिर अनुरोध के क्रमबद्ध किए गए डेटा का SHA256.
  3. ऐप्लिकेशन-साइड और सर्वर-साइड डाइजेस्ट की तुलना करें. अगर ये मेल नहीं खाते हैं, तो अनुरोध पर भरोसा नहीं किया जा सकता.

रीप्ले अटैक से बचने के लिए, यूनीक वैल्यू शामिल करें

Play Integrity API से मिले पिछले जवाबों का गलत इस्तेमाल करने वाले लोगों को रोकने के लिए, nonce फ़ील्ड का इस्तेमाल किया जा सकता है. इससे हर मैसेज की पहचान की जा सकती है.

इंटिग्रिटी के नतीजे का अनुरोध करने पर:

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

इंटिग्रिटी के नतीजे मिलने पर:

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

छेड़छाड़ और रीप्ले अटैक से सुरक्षा देने वाली दोनों सुविधाओं को एक साथ इस्तेमाल करना (सुझाया गया)

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

इंटिग्रिटी के नतीजे का अनुरोध करने पर:

  1. उपयोगकर्ता, ज़्यादा वैल्यू वाली कार्रवाई शुरू करता है.
  2. इस कार्रवाई के लिए, रीप्ले अटैक से बचने के लिए, यूनीक वैल्यू शामिल करें सेक्शन में बताए गए तरीके से यूनीक वैल्यू पाएं.
  3. वह मैसेज तैयार करें जिसे सुरक्षित करना है. मैसेज में, दूसरे चरण में मिली यूनीक वैल्यू शामिल करें.
  4. आपका ऐप्लिकेशन, उस मैसेज का डाइजेस्ट बनाता है जिसे सुरक्षित रखना है. इसके बारे में छेड़छाड़ से बचाने के लिए, अनुरोध हैश शामिल करें सेक्शन में बताया गया है. मैसेज में यूनीक वैल्यू मौजूद है. इसलिए, यूनीक वैल्यू हैश का हिस्सा है.
  5. nonce फ़ील्ड को पिछले चरण से कंप्यूट किए गए डाइजेस्ट पर सेट करने के लिए, setNonce() का इस्तेमाल करें.

इंटिग्रिटी के नतीजे मिलने पर:

  1. अनुरोध से यूनीक वैल्यू पाना
  2. इंटेग्रिटी टोकन को डिकोड करें और उसकी पुष्टि करें. साथ ही, nonce फ़ील्ड से डाइजेस्ट पाएं.
  3. छेड़छाड़ से बचाने के लिए, अनुरोध हैश शामिल करें सेक्शन में बताए गए तरीके से, सर्वर साइड पर डाइजेस्ट को फिर से कैलकुलेट करें. साथ ही, यह देखें कि यह इंटिग्रिटी टोकन से मिले डाइजेस्ट से मेल खाता हो.
  4. रीप्ले अटैक से बचने के लिए, यूनीक वैल्यू शामिल करें सेक्शन में बताए गए तरीके से, यूनीक वैल्यू की पुष्टि करें.

नीचे दिए गए क्रम के डायग्राम में, सर्वर-साइड nonce का इस्तेमाल करके इन चरणों को दिखाया गया है:

दूसरी इमेज. सीक्वेंस डायग्राम, जिसमें छेड़छाड़ और रीप्ले के हमलों से बचने का तरीका दिखाया गया है.

इंटिग्रिटी की जांच के नतीजे का अनुरोध करना

nonce जनरेट करने के बाद, Google Play से इंटिग्रिटी की जांच के नतीजे का अनुरोध किया जा सकता है. इसके लिए, यह तरीका अपनाएं:

  1. नीचे दिए गए उदाहरणों में दिखाए गए तरीके से, IntegrityManager बनाएं.
  2. IntegrityTokenRequest बनाएं. इसके लिए, nonce को उससे जुड़े बिल्डर में setNonce() तरीके से उपलब्ध कराएं. Google Play के बाहर डिस्ट्रिब्यूट किए जाने वाले ऐप्लिकेशन और एसडीके को भी setCloudProjectNumber() तरीके से, अपने Google Cloud प्रोजेक्ट का नंबर बताना होगा. Google Play पर मौजूद ऐप्लिकेशन, Play Console में किसी Cloud प्रोजेक्ट से लिंक होते हैं. इसलिए, उन्हें अनुरोध में Cloud प्रोजेक्ट नंबर सेट करने की ज़रूरत नहीं होती.
  3. मैनेजर का इस्तेमाल करके requestIntegrityToken() को कॉल करें और IntegrityTokenRequest उपलब्ध कराएं.

Kotlin

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

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

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

Java

import com.google.android.gms.tasks.Task; ...

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

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

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

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();
}

Unreal Engine

// .h
void MyClass::OnRequestIntegrityTokenCompleted(
  EIntegrityErrorCode ErrorCode,
  UIntegrityTokenResponse* Response)
{
  // Check the resulting error code.
  if (ErrorCode == EIntegrityErrorCode::Integrity_NO_ERROR)
  {
    // Get the token.
    FString Token = Response->Token;
  }
}

// .cpp
void MyClass::RequestIntegrityToken()
{
  // Receive the nonce from the secure server.
  FString Nonce = ...

  // Create the Integrity Token Request.
  FIntegrityTokenRequest Request = { Nonce };

  // Create a delegate to bind the callback function.
  FIntegrityOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnRequestIntegrityTokenCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnRequestIntegrityTokenCompleted);

  // Initiate the integrity token request, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UIntegrityManager>()
    ->RequestIntegrityToken(Request, Delegate);
}

मूल भाषा वाला

/// 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.
/// Note, the polling shouldn't block the thread where the IntegrityManager
/// is running.

IntegrityResponseStatus response_status;

/// Check for error codes.
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();

इंटिग्रिटी के नतीजे को डिक्रिप्ट करना और उसकी पुष्टि करना

इंटिग्रिटी की जांच के नतीजे का अनुरोध करने पर, Play Integrity API आपको हस्ताक्षर किया गया रिस्पॉन्स टोकन देता है. आपके अनुरोध में शामिल किया गया nonce, रिस्पॉन्स टोकन का हिस्सा बन जाता है.

टोकन का फ़ॉर्मैट

यह टोकन, नेस्ट किया गया JSON Web Token (JWT) है. यह JSON Web Signature (JWS) का JSON Web Encryption (JWE) है. JWE और JWS कॉम्पोनेंट को कॉम्पैक्ट सीरियलाइज़ेशन का इस्तेमाल करके दिखाया जाता है .

एन्क्रिप्शन / साइनिंग एल्गोरिदम, अलग-अलग JWT के साथ काम करते हैं:

  • JWE, alg के लिए A256KW और enc के लिए A256GCM का इस्तेमाल करता है

  • JWS, ES256 का इस्तेमाल करता है.

Google के सर्वर पर डिक्रिप्ट करना और पुष्टि करना (सुझाया गया)

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

  1. अपने ऐप्लिकेशन से लिंक किए गए Google Cloud प्रोजेक्ट में, एक सेवा खाता बनाएं.
  2. अपने ऐप्लिकेशन के सर्वर पर, playintegrity स्कोप का इस्तेमाल करके, अपने सेवा खाते के क्रेडेंशियल से ऐक्सेस टोकन फ़ेच करें. इसके बाद, यह अनुरोध करें:

    playintegrity.googleapis.com/v1/PACKAGE_NAME:decodeIntegrityToken -d \
    '{ "integrity_token": "INTEGRITY_TOKEN" }'
  3. JSON फ़ॉर्मैट में मिले जवाब को पढ़ें.

स्थानीय तौर पर डिक्रिप्ट और पुष्टि करना

जवाब को एन्क्रिप्ट करने की कुंजियों को मैनेज और डाउनलोड करने का विकल्प चुनने पर, आपके पास अपने सुरक्षित सर्वर एनवायरमेंट में, वापस भेजे गए टोकन को डिक्रिप्ट और उसकी पुष्टि करने का विकल्प होता है. IntegrityTokenResponse#token() तरीके का इस्तेमाल करके, लौटाया गया टोकन पाया जा सकता है.

यहां दिए गए उदाहरण में, यह दिखाया गया है कि Play Console से हस्ताक्षर की पुष्टि करने के लिए, AES कुंजी और DER-कोड वाली सार्वजनिक EC कुंजी को ऐप्लिकेशन के बैकएंड में, भाषा के हिसाब से (हमारे मामले में, Java प्रोग्रामिंग भाषा) कुंजियों में कैसे डिकोड किया जाता है. ध्यान दें कि कुंजियों को डिफ़ॉल्ट फ़्लैग का इस्तेमाल करके, base64 कोड में बदला जाता है.

Kotlin

// base64OfEncodedDecryptionKey is provided through Play Console.
var decryptionKeyBytes: ByteArray =
    Base64.decode(base64OfEncodedDecryptionKey, Base64.DEFAULT)

// Deserialized encryption (symmetric) key.
var decryptionKey: SecretKey = SecretKeySpec(
    decryptionKeyBytes,
    /* offset= */ 0,
    AES_KEY_SIZE_BYTES,
    AES_KEY_TYPE
)

// base64OfEncodedVerificationKey is provided through Play Console.
var encodedVerificationKey: ByteArray =
    Base64.decode(base64OfEncodedVerificationKey, Base64.DEFAULT)

// Deserialized verification (public) key.
var verificationKey: PublicKey = KeyFactory.getInstance(EC_KEY_TYPE)
    .generatePublic(X509EncodedKeySpec(encodedVerificationKey))

Java

// base64OfEncodedDecryptionKey is provided through Play Console.
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.
byte[] encodedVerificationKey =
    Base64.decode(base64OfEncodedVerificationKey, Base64.DEFAULT);
// Deserialized verification (public) key.
PublicKey verificationKey =
    KeyFactory.getInstance(EC_KEY_TYPE)
        .generatePublic(new X509EncodedKeySpec(encodedVerificationKey));

इसके बाद, इन कुंजियों का इस्तेमाल करके, पहले इंटिग्रिटी टोकन (JWE हिस्सा) को डिक्रिप्ट करें. इसके बाद, नेस्ट किए गए JWS हिस्से की पुष्टि करें और उसे निकालें.

Kotlin

val jwe: JsonWebEncryption =
    JsonWebStructure.fromCompactSerialization(integrityToken) as JsonWebEncryption
jwe.setKey(decryptionKey)

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

val jws: JsonWebSignature =
    JsonWebStructure.fromCompactSerialization(compactJws) as JsonWebSignature
jws.setKey(verificationKey)

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

Java

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();

इससे मिलने वाला पेलोड, सादे टेक्स्ट वाला एक टोकन होता है. इसमें integrity verdicts शामिल होते हैं.

Google Play प्रॉम्प्ट की मदद से, फ़ैसले से जुड़ी समस्याओं को ठीक करना (ज़रूरी नहीं)

आपके सर्वर को इंटिग्रिटी का नतीजा मिलने के बाद, सर्वर यह तय कर सकता है कि आगे क्या करना है. अगर फ़ैसले से पता चलता है कि कोई समस्या है, जैसे कि ऐप्लिकेशन का लाइसेंस न होना, उसमें छेड़छाड़ होना या डिवाइस से समझौता किया गया है, तो उपयोगकर्ताओं को समस्या ठीक करने का मौका दिया जा सकता है.

Play Integrity API, Google Play का एक डायलॉग बॉक्स दिखाने का विकल्प देता है. इससे उपयोगकर्ता को कार्रवाई करने के लिए कहा जाता है. उदाहरण के लिए, Google Play से आपके ऐप्लिकेशन का आधिकारिक वर्शन पाने के लिए.

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