এই পৃষ্ঠায় ফেরত আসা ইন্টিগ্রিটি ভার্ডিক্ট কীভাবে ব্যাখ্যা করতে হয় এবং তা নিয়ে কাজ করতে হয়, তা বর্ণনা করা হয়েছে। আপনি স্ট্যান্ডার্ড বা ক্লাসিক এপিআই অনুরোধ, যা-ই করুন না কেন, ইন্টিগ্রিটি ভার্ডিক্ট একই ফরম্যাটে এবং প্রায় একই ধরনের বিষয়বস্তুসহ ফেরত আসে। ইন্টিগ্রিটি ভার্ডিক্ট ডিভাইস, অ্যাপ এবং অ্যাকাউন্টের বৈধতা সম্পর্কে তথ্য প্রদান করে। আপনার অ্যাপের সার্ভার, ডিক্রিপ্ট করা ও যাচাইকৃত ভার্ডিক্টের পেলোড ব্যবহার করে, আপনার অ্যাপের কোনো নির্দিষ্ট কাজ বা অনুরোধ নিয়ে কীভাবে সবচেয়ে ভালোভাবে এগোনো যায়, তা নির্ধারণ করতে পারে।
ফেরত দেওয়া অখণ্ডতা রায়ের বিন্যাস
পেলোডটি হলো প্লেইন-টেক্সট 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 মূল অনুরোধে পাঠানো তথ্যের সাথে মিলছে, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:
কোটলিন
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. ... }
জাভা
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 মূল অনুরোধে পাঠানো তথ্যের সাথে মিলছে, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:
কোটলিন
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. ... }
জাভা
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 - অ্যাপ এবং সার্টিফিকেটটি গুগল প্লে দ্বারা বিতরণ করা সংস্করণগুলোর সাথে মিলে যায়।
-
UNRECOGNIZED_VERSION - সার্টিফিকেট বা প্যাকেজের নামটি গুগল প্লে-র রেকর্ডের সাথে মেলে না।
-
UNEVALUATED - অ্যাপ্লিকেশনের অখণ্ডতা মূল্যায়ন করা হয়নি। একটি প্রয়োজনীয় শর্ত পূরণ করা হয়নি, যেমন ডিভাইসটি যথেষ্ট নির্ভরযোগ্য না হওয়া।
টোকেনটি আপনার তৈরি করা অ্যাপ দ্বারা জেনারেট করা হয়েছে কিনা তা নিশ্চিত করতে, নিম্নলিখিত কোড স্নিপেটে দেখানো অনুযায়ী অ্যাপ্লিকেশনটির ইন্টিগ্রিটি প্রত্যাশিত অবস্থায় আছে কিনা তা যাচাই করুন:
কোটলিন
val appIntegrity = JSONObject(payload).getJSONObject("appIntegrity") val appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict") if (appRecognitionVerdict == "PLAY_RECOGNIZED") { // Looks good! }
জাভা
JSONObject appIntegrity = new JSONObject(payload).getJSONObject("appIntegrity"); String appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict"); if (appRecognitionVerdict.equals("PLAY_RECOGNIZED")) { // Looks good! }
এছাড়াও আপনি অ্যাপ প্যাকেজ নেম, অ্যাপ ভার্সন এবং অ্যাপ সার্টিফিকেটগুলো ম্যানুয়ালি যাচাই করতে পারেন।
ডিভাইসের অখণ্ডতা ক্ষেত্র
deviceIntegrity ফিল্ডটিতে deviceRecognitionVerdict নামে একটি একক ভ্যালু থাকতে পারে, যেখানে এক বা একাধিক লেবেল থাকে যা নির্দেশ করে একটি ডিভাইস অ্যাপের অখণ্ডতা কতটা ভালোভাবে রক্ষা করতে পারে। যদি কোনো ডিভাইস কোনো লেবেলের মানদণ্ড পূরণ না করে, তাহলে deviceIntegrity ফিল্ড থেকে deviceRecognitionVerdict বাদ দেওয়া হয়।
"deviceIntegrity": { // "MEETS_DEVICE_INTEGRITY" is one of several possible values. "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"] }
ডিফল্টরূপে, deviceRecognitionVerdict নিম্নলিখিত বিষয়গুলো থাকতে পারে:
-
MEETS_DEVICE_INTEGRITY - অ্যাপটি একটি আসল এবং প্রত্যয়িত অ্যান্ড্রয়েড ডিভাইসে চলছে। অ্যান্ড্রয়েড ১৩ এবং তার পরবর্তী সংস্করণগুলোতে হার্ডওয়্যার-সমর্থিত প্রমাণ রয়েছে যে, ডিভাইসটির বুটলোডার লক করা আছে এবং লোড হওয়া অ্যান্ড্রয়েড ওএসটি ডিভাইস প্রস্তুতকারকের একটি প্রত্যয়িত ইমেজ।
- খালি (একটি ফাঁকা মান)
- অ্যাপটি এমন একটি ডিভাইসে চলছে যেটিতে আক্রমণের (যেমন এপিআই হুকিং) বা সিস্টেমের ত্রুটির (যেমন রুটেড হওয়া) লক্ষণ রয়েছে, অথবা অ্যাপটি কোনো বাস্তব ডিভাইসে চলছে না (যেমন এমন একটি এমুলেটর যা গুগল প্লে-এর ইন্টিগ্রিটি চেক পাস করে না)।
টোকেনটি একটি বিশ্বস্ত ডিভাইস থেকে এসেছে কিনা তা নিশ্চিত করতে, নিম্নলিখিত কোড স্নিপেটে দেখানো অনুযায়ী deviceRecognitionVerdict প্রত্যাশিত কিনা তা যাচাই করুন:
কোটলিন
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! }
জাভা
JSONObject deviceIntegrity = new JSONObject(payload).getJSONObject("deviceIntegrity"); String deviceRecognitionVerdict = deviceIntegrity.has("deviceRecognitionVerdict") ? deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString() : ""; if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) { // Looks good! }
আপনার টেস্টিং ডিভাইসটি ডিভাইস ইন্টিগ্রিটি পূরণে ব্যর্থ হলে, ফ্যাক্টরি রম ইনস্টল করা আছে কিনা (উদাহরণস্বরূপ, ডিভাইসটি রিসেট করে) এবং বুটলোডারটি লক করা আছে কিনা তা নিশ্চিত করুন। এছাড়াও আপনি আপনার প্লে কনসোলে প্লে ইন্টিগ্রিটি এপিআই টেস্ট তৈরি করতে পারেন।
শর্তসাপেক্ষ ডিভাইস লেবেল
আপনার অ্যাপটি যদি পিসির জন্য গুগল প্লে গেমসে প্রকাশ করা হয়, তাহলে deviceRecognitionVerdict এ নিম্নলিখিত লেবেলটিও থাকতে পারে:
-
MEETS_VIRTUAL_INTEGRITY - অ্যাপটি গুগল প্লে সার্ভিসসহ একটি অ্যান্ড্রয়েড-চালিত এমুলেটরে চলছে। এমুলেটরটি সিস্টেমের অখণ্ডতা যাচাইয়ে উত্তীর্ণ হয়েছে এবং অ্যান্ড্রয়েডের মূল সামঞ্জস্যতার প্রয়োজনীয়তাগুলো পূরণ করে।
ঐচ্ছিক ডিভাইসের তথ্য এবং ডিভাইস প্রত্যাহার
আপনি একটি স্তরভিত্তিক প্রয়োগ কৌশলের অংশ হিসেবে ঐচ্ছিক ডিভাইস লেবেল গ্রহণ করার জন্য সম্মতি জানাতে পারেন। আপনি যদি ইন্টিগ্রিটি ভারডিক্টে অতিরিক্ত লেবেল গ্রহণ করার জন্য সম্মতি জানান , তাহলে deviceRecognitionVerdict নিম্নলিখিত অতিরিক্ত লেবেলগুলো থাকতে পারে:
-
MEETS_BASIC_INTEGRITY - অ্যাপটি এমন একটি ডিভাইসে চলছে যা বেসিক সিস্টেম ইন্টিগ্রিটি চেক পাস করে। ডিভাইসটির বুটলোডার লক বা আনলক করা থাকতে পারে এবং বুট স্টেট ভেরিফাইড বা আনভেরিফাইড হতে পারে। ডিভাইসটি সার্টিফায়েড নাও হতে পারে, সেক্ষেত্রে গুগল কোনো নিরাপত্তা, গোপনীয়তা বা অ্যাপ কম্প্যাটিবিলিটির নিশ্চয়তা দিতে পারে না। অ্যান্ড্রয়েড ১৩ এবং তার পরবর্তী সংস্করণগুলোতে,
MEETS_BASIC_INTEGRITYভারডিক্টের জন্য শুধুমাত্র এইটুকু প্রয়োজন যে, অ্যাটেস্টেশন রুট অফ ট্রাস্ট গুগল দ্বারা সরবরাহ করা হয়েছে। -
MEETS_STRONG_INTEGRITY - অ্যাপটি সাম্প্রতিক নিরাপত্তা আপডেটসহ একটি আসল ও প্রত্যয়িত অ্যান্ড্রয়েড ডিভাইসে চলছে।
- অ্যান্ড্রয়েড ১৩ এবং এর পরবর্তী সংস্করণগুলোতে,
MEETS_STRONG_INTEGRITYভার্ডিক্টের জন্যMEETS_DEVICE_INTEGRITYভার্ডিক্ট এবং ডিভাইসের সমস্ত পার্টিশনের জন্য গত এক বছরের মধ্যে সিকিউরিটি আপডেট প্রয়োজন, যার মধ্যে একটি অ্যান্ড্রয়েড ওএস পার্টিশন প্যাচ এবং একটি ভেন্ডর পার্টিশন প্যাচ অন্তর্ভুক্ত। - অ্যান্ড্রয়েড ১২ এবং এর নিচের সংস্করণগুলোতে,
MEETS_STRONG_INTEGRITYভার্ডিক্টটির জন্য শুধুমাত্র হার্ডওয়্যার-সমর্থিত বুট ইন্টিগ্রিটির প্রমাণ প্রয়োজন হয় এবং ডিভাইসটিতে সাম্প্রতিক কোনো সিকিউরিটি আপডেট থাকার প্রয়োজন নেই । তাই,MEETS_STRONG_INTEGRITYব্যবহার করার সময়,deviceAttributesফিল্ডে অ্যান্ড্রয়েড SDK ভার্সনটিও বিবেচনায় রাখার পরামর্শ দেওয়া হয়।
- অ্যান্ড্রয়েড ১৩ এবং এর পরবর্তী সংস্করণগুলোতে,
একটি একক ডিভাইস তার অখণ্ডতার রায়ে একাধিক ডিভাইস লেবেল ফেরত দেবে, যদি লেবেলটির প্রতিটি মানদণ্ড পূরণ হয়।
ডিভাইসের বৈশিষ্ট্য
আপনি ডিভাইস অ্যাট্রিবিউটগুলোও বেছে নিতে পারেন, যা ডিভাইসে চলমান অ্যান্ড্রয়েড ওএস-এর অ্যান্ড্রয়েড এসডিকে সংস্করণ সম্পর্কে জানায়। একটি স্তরভিত্তিক প্রয়োগ কৌশলের অংশ হিসেবে, অ্যান্ড্রয়েড ১৩ বা তার উচ্চতর সংস্করণ চালিত ডিভাইস এবং নিম্নতর অ্যান্ড্রয়েড এসডিকে সংস্করণ চালিত ডিভাইসগুলোর মধ্যে পার্থক্য করতে অ্যান্ড্রয়েড এসডিকে সংস্করণটি কার্যকর। ভবিষ্যতে, এটিকে অন্যান্য ডিভাইস অ্যাট্রিবিউট দিয়ে আরও সম্প্রসারিত করা হতে পারে।
SDK ভার্সন ভ্যালুটি হলো Build.VERSION_CODES এ সংজ্ঞায়িত অ্যান্ড্রয়েড SDK ভার্সন নম্বর। কোনো প্রয়োজনীয় শর্ত পূরণ না হলে SDK ভার্সনটি মূল্যায়ন করা হয় না। এই ক্ষেত্রে, sdkVersion ফিল্ডটি আনসেট থাকে; ফলে, deviceAttributes ফিল্ডটি খালি থাকে। এটি নিম্নলিখিত কারণে ঘটতে পারে:
- ডিভাইসটি যথেষ্ট নির্ভরযোগ্য নয়।
- ডিভাইসটিতে প্রযুক্তিগত সমস্যা ছিল।
আপনি যদি 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. }
সাম্প্রতিক ডিভাইস কার্যকলাপ
আপনি সাম্প্রতিক ডিভাইস কার্যকলাপও বেছে নিতে পারেন, যা আপনাকে জানায় যে গত এক ঘণ্টায় আপনার অ্যাপ একটি নির্দিষ্ট ডিভাইসে কতবার ইন্টিগ্রিটি টোকেনের জন্য অনুরোধ করেছে। আপনি অপ্রত্যাশিত, অতি-সক্রিয় ডিভাইসগুলো থেকে আপনার অ্যাপকে সুরক্ষিত রাখতে সাম্প্রতিক ডিভাইস কার্যকলাপ ব্যবহার করতে পারেন, যা একটি সক্রিয় আক্রমণের ইঙ্গিত হতে পারে। একটি সাধারণ ডিভাইসে ইনস্টল করা আপনার অ্যাপ প্রতি ঘণ্টায় কতবার ইন্টিগ্রিটি টোকেনের জন্য অনুরোধ করবে বলে আপনি আশা করেন, তার উপর ভিত্তি করে আপনি প্রতিটি সাম্প্রতিক ডিভাইস কার্যকলাপের স্তরকে কতটা বিশ্বাস করবেন তা নির্ধারণ করতে পারেন।
আপনি যদি recentDeviceActivity গ্রহণ করতে সম্মতি দেন, তাহলে deviceIntegrity ফিল্ডটির দুটি মান থাকবে:
"deviceIntegrity": { "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"], "recentDeviceActivity": { // "LEVEL_2" is one of several possible values. "deviceActivityLevel": "LEVEL_2" } }
মোডভেদে deviceActivityLevel সংজ্ঞা ভিন্ন হয় এবং এর মান নিম্নলিখিত মানগুলোর মধ্যে যেকোনো একটি হতে পারে:
| সাম্প্রতিক ডিভাইস কার্যকলাপের স্তর | গত এক ঘণ্টায় এই ডিভাইসে প্রতি অ্যাপে স্ট্যান্ডার্ড এপিআই ইন্টিগ্রিটি টোকেন অনুরোধ | এই ডিভাইসে গত এক ঘণ্টায় প্রতি অ্যাপে ক্লাসিক এপিআই ইন্টিগ্রিটি টোকেন অনুরোধ |
|---|---|---|
LEVEL_1 (সর্বনিম্ন) | ১০ বা তার কম | ৫ বা তার কম |
LEVEL_2 | ১১ থেকে ২৫ এর মধ্যে | ৬ থেকে ১০ এর মধ্যে |
LEVEL_3 | ২৬ থেকে ৫০ এর মধ্যে | ১১ থেকে ১৫ এর মধ্যে |
LEVEL_4 (সর্বোচ্চ) | ৫০ এর বেশি | ১৫টিরও বেশি |
UNEVALUATED | সাম্প্রতিক ডিভাইস কার্যকলাপ মূল্যায়ন করা হয়নি। এটি নিম্নলিখিত কারণে ঘটতে পারে:
| |
ডিভাইস প্রত্যাহার (বিটা)
আপনি ডিভাইস রিকল বিকল্পটিও বেছে নিতে পারেন, যা আপনাকে নির্দিষ্ট কিছু ডিভাইসের সাথে প্রতিটি ডিভাইসের জন্য কিছু কাস্টম ডেটা সংরক্ষণ করার সুযোগ দেয়। পরবর্তীতে একই ডিভাইসে আপনার অ্যাপটি পুনরায় ইনস্টল করা হলে আপনি সেই ডেটা নির্ভরযোগ্যভাবে পুনরুদ্ধার করতে পারবেন। একটি ইন্টিগ্রিটি টোকেনের জন্য অনুরোধ করার পর, একটি নির্দিষ্ট ডিভাইসের জন্য ডিভাইস রিকলের মান পরিবর্তন করতে আপনাকে আলাদাভাবে সার্ভার-টু-সার্ভার কল করতে হয়।
আপনি যদি deviceRecall বিকল্পটি বেছে নেন, তাহলে deviceIntegrity ফিল্ডটিতে নির্দিষ্ট ডিভাইসটির জন্য আপনার সেট করা ডিভাইস রিকল সংক্রান্ত তথ্য থাকবে:
"deviceIntegrity": {
"deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
"deviceRecall": {
"values": {
"bitFirst": true,
"bitSecond": false,
"bitThird": true
},
"writeDates": {
// Write time in YYYYMM format in UTC.
"yyyymmFirst": 202401,
// Note that yyyymmSecond is not set because bitSecond is false.
"yyyymmThird": 202310
}
}
}
deviceRecall রিকল দুটি ক্ষেত্রে বিভক্ত:
-
values: এই ডিভাইসের জন্য আপনি পূর্বে যে বিট মানগুলো সেট করেছিলেন, সেগুলো স্মরণ করুন। -
writeDates: UTC অনুযায়ী বছর ও মাস নির্ভুলভাবে বিটের লেখার তারিখগুলো স্মরণ করুন। একটি রিকল বিটের লেখার তারিখ প্রতিবার বিটটিtrueসেট করা হলে আপডেট করা হবে এবং বিটটি 'falseসেট করা হলে মুছে ফেলা হবে।
যখন ডিভাইস রিকল সংক্রান্ত তথ্য পাওয়া যায় না, তখন ডিভাইস রিকল ভ্যালুটি খালি থাকবে:
"deviceIntegrity": {
"deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
"deviceRecall": {
"values": {},
"writeDates": {}
}
}
অ্যাকাউন্টের বিবরণ ক্ষেত্র
accountDetails ফিল্ডটিতে appLicensingVerdict নামে একটিমাত্র ভ্যালু থাকে, যা ডিভাইসে সাইন ইন করা ইউজার অ্যাকাউন্টের জন্য অ্যাপটির গুগল প্লে লাইসেন্সিং স্ট্যাটাস নির্দেশ করে। যদি ইউজার অ্যাকাউন্টটির অ্যাপটির জন্য প্লে লাইসেন্স থাকে, তার মানে হলো তিনি অ্যাপটি গুগল প্লে থেকে ডাউনলোড করেছেন বা কিনেছেন।
"accountDetails": { // This field can be LICENSED, UNLICENSED, or UNEVALUATED. "appLicensingVerdict": "LICENSED" }
appLicensingVerdict নিম্নলিখিত মানগুলির মধ্যে যেকোনো একটি থাকতে পারে:
-
LICENSED - ব্যবহারকারীর অ্যাপটি ব্যবহারের অধিকার আছে। অন্য কথায়, ব্যবহারকারী তার ডিভাইসে গুগল প্লে থেকে আপনার অ্যাপটি ইনস্টল বা আপডেট করেছেন।
-
UNLICENSED - ব্যবহারকারীর অ্যাপ ব্যবহারের অনুমতি নেই। উদাহরণস্বরূপ, ব্যবহারকারী যখন আপনার অ্যাপটি সাইডলোড করে অথবা গুগল প্লে থেকে এটি সংগ্রহ করে না, তখন এমনটা ঘটে। এর প্রতিকারের জন্য আপনি ব্যবহারকারীদের GET_LICENSED ডায়ালগটি দেখাতে পারেন।
-
UNEVALUATED একটি প্রয়োজনীয় শর্ত পূরণ না হওয়ায় লাইসেন্স সংক্রান্ত বিবরণ মূল্যায়ন করা হয়নি।
এটি বিভিন্ন কারণে ঘটতে পারে, যার মধ্যে নিম্নলিখিতগুলো অন্তর্ভুক্ত:
- ডিভাইসটি যথেষ্ট নির্ভরযোগ্য নয়।
- আপনার ডিভাইসে ইনস্টল করা অ্যাপের সংস্করণটি গুগল প্লে-র কাছে অজানা।
- ব্যবহারকারী গুগল প্লে-তে সাইন ইন করেননি।
ব্যবহারকারীর আপনার অ্যাপের জন্য অ্যাপ এনটাইটেলমেন্ট আছে কিনা তা পরীক্ষা করতে, নিম্নলিখিত কোড স্নিপেটে দেখানো অনুযায়ী appLicensingVerdict প্রত্যাশিত কিনা তা যাচাই করুন:
কোটলিন
val accountDetails = JSONObject(payload).getJSONObject("accountDetails") val appLicensingVerdict = accountDetails.getString("appLicensingVerdict") if (appLicensingVerdict == "LICENSED") { // Looks good! }
জাভা
JSONObject accountDetails = new JSONObject(payload).getJSONObject("accountDetails"); String appLicensingVerdict = accountDetails.getString("appLicensingVerdict"); if (appLicensingVerdict.equals("LICENSED")) { // Looks good! }
পরিবেশের বিশদ ক্ষেত্র
আপনি পরিবেশ সম্পর্কিত অতিরিক্ত সংকেত গ্রহণ করার বিকল্পও বেছে নিতে পারেন। অ্যাপ অ্যাক্সেস রিস্ক আপনার অ্যাপকে জানায় যে, এমন কোনো অ্যাপ চলছে কি না যা স্ক্রিন ক্যাপচার করতে, ওভারলে প্রদর্শন করতে বা ডিভাইসটি নিয়ন্ত্রণ করতে ব্যবহার করা যেতে পারে। প্লে প্রোটেক্ট ভারডিক্ট আপনাকে জানায় যে, ডিভাইসটিতে গুগল প্লে প্রোটেক্ট চালু আছে কি না এবং এটি কোনো পরিচিত ম্যালওয়্যার খুঁজে পেয়েছে কি না।
আপনি যদি আপনার গুগল প্লে কনসোলে ‘অ্যাপ অ্যাক্সেস রিস্ক’ বা ‘প্লে প্রোটেক্ট’ ভার্ডিক্ট বেছে নিয়ে থাকেন, তাহলে আপনার এপিআই রেসপন্সে environmentDetails ফিল্ডটি অন্তর্ভুক্ত থাকবে। environmentDetails ফিল্ডটিতে দুটি ভ্যালু থাকতে পারে: appAccessRiskVerdict এবং playProtectVerdict ’।
অ্যাপ অ্যাক্সেস ঝুঁকির রায়
একবার সক্রিয় করা হলে, প্লে ইন্টিগ্রিটি এপিআই পেলোডের 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 একটি ফিল্ড থাকে, যেখানে এক বা একাধিক প্রতিক্রিয়া থাকতে পারে। শনাক্তকৃত অ্যাপগুলোর ইনস্টলের উৎসের উপর নির্ভর করে এই প্রতিক্রিয়াগুলো নিম্নলিখিত দুটি গ্রুপের যেকোনো একটিতে পড়ে:
প্লে বা সিস্টেম অ্যাপস : যে অ্যাপগুলো গুগল প্লে দ্বারা ইনস্টল করা হয় অথবা ডিভাইস প্রস্তুতকারক দ্বারা ডিভাইসের সিস্টেম পার্টিশনে (
FLAG_SYSTEMদ্বারা চিহ্নিত) আগে থেকেই লোড করা থাকে। এই ধরনের অ্যাপের প্রতিক্রিয়ার শুরুতেKNOWN_যুক্ত থাকে।অন্যান্য অ্যাপ : যে অ্যাপগুলো গুগল প্লে দ্বারা ইনস্টল করা হয় না। এর মধ্যে ডিভাইস প্রস্তুতকারকের দ্বারা সিস্টেম পার্টিশনে আগে থেকে লোড করা অ্যাপগুলো অন্তর্ভুক্ত নয়। এই ধরনের অ্যাপের ক্ষেত্রে প্রতিক্রিয়ার শুরুতে
UNKNOWN_যুক্ত থাকে।
নিম্নলিখিত প্রতিক্রিয়াগুলি ফেরত দেওয়া যেতে পারে:
-
KNOWN_INSTALLED,UNKNOWN_INSTALLED - সংশ্লিষ্ট ইনস্টল সোর্সের সাথে মেলে এমন অ্যাপ ইনস্টল করা আছে।
-
KNOWN_CAPTURING,UNKNOWN_CAPTURING - এমন কিছু অ্যাপ চালু আছে যেগুলোর অনুমতি সক্রিয় করা আছে, যা আপনার অ্যাপটি চলার সময় স্ক্রিনটি দেখার জন্য ব্যবহার করা যেতে পারে। ডিভাইসে চলমান Google Play দ্বারা স্বীকৃত কোনো যাচাইকৃত অ্যাক্সেসিবিলিটি পরিষেবা এর অন্তর্ভুক্ত নয়।
-
KNOWN_CONTROLLING,UNKNOWN_CONTROLLING - এমন কিছু অ্যাপ চালু আছে যেগুলোর অনুমতি সক্রিয় করা আছে, যা দিয়ে ডিভাইসটি নিয়ন্ত্রণ করা, আপনার অ্যাপের ইনপুট সরাসরি নিয়ন্ত্রণ করা এবং আপনার অ্যাপের ইনপুট ও আউটপুট ক্যাপচার করা যেতে পারে। ডিভাইসে চলমান Google Play দ্বারা স্বীকৃত কোনো যাচাইকৃত অ্যাক্সেসিবিলিটি পরিষেবা এর অন্তর্ভুক্ত নয়।
-
KNOWN_OVERLAYS,UNKNOWN_OVERLAYS - এমন কিছু অ্যাপ চালু আছে যেগুলোর অনুমতি সক্রিয় করা আছে, যা আপনার অ্যাপে ওভারলে প্রদর্শন করতে ব্যবহার করা যেতে পারে। ডিভাইসে চলমান Google Play দ্বারা স্বীকৃত কোনো যাচাইকৃত অ্যাক্সেসিবিলিটি পরিষেবা এর অন্তর্ভুক্ত নয়।
- খালি (একটি ফাঁকা মান)
যদি কোনো প্রয়োজনীয় শর্ত পূরণ না হয়, তবে অ্যাপ অ্যাক্সেসের ঝুঁকি মূল্যায়ন করা হয় না। এক্ষেত্রে
appAccessRiskVerdictফিল্ডটি খালি থাকে। এটি বিভিন্ন কারণে ঘটতে পারে, যার মধ্যে নিম্নলিখিতগুলো অন্তর্ভুক্ত:- ডিভাইসটি যথেষ্ট নির্ভরযোগ্য নয়।
- ডিভাইসটির ফর্ম ফ্যাক্টর ফোন, ট্যাবলেট বা ফোল্ডেবল নয়।
- ডিভাইসটি অ্যান্ড্রয়েড ৬ (এপিআই লেভেল ২৩) বা তার উচ্চতর সংস্করণে চলছে না।
- আপনার ডিভাইসে ইনস্টল করা অ্যাপের সংস্করণটি গুগল প্লে-র কাছে অজানা।
- ডিভাইসটিতে থাকা গুগল প্লে স্টোরের সংস্করণটি পুরোনো।
- ব্যবহারকারী অ্যাকাউন্টটির কোনো প্লে লাইসেন্স নেই।
-
verdictOptOutপ্যারামিটারসহ একটি স্ট্যান্ডার্ড অনুরোধ ব্যবহার করা হয়েছিল। - প্লে ইন্টিগ্রিটি এপিআই লাইব্রেরির এমন একটি সংস্করণের সাথে একটি স্ট্যান্ডার্ড রিকোয়েস্ট ব্যবহার করা হয়েছিল, যা এখনও স্ট্যান্ডার্ড রিকোয়েস্টের জন্য অ্যাপ অ্যাক্সেস ঝুঁকি সমর্থন করে না।
অ্যাপ অ্যাক্সেস রিস্ক স্বয়ংক্রিয়ভাবে সেইসব ভেরিফাইড অ্যাক্সেসিবিলিটি সার্ভিসকে বাদ দেয়, যেগুলো একটি এনহ্যান্সড গুগল প্লে অ্যাক্সেসিবিলিটি রিভিউয়ের মধ্য দিয়ে গেছে (ডিভাইসের যেকোনো অ্যাপ স্টোর থেকে ইনস্টল করা হলে)। "বাদ দেওয়া হয়েছে" এর অর্থ হলো, ডিভাইসে চলমান ভেরিফাইড অ্যাক্সেসিবিলিটি সার্ভিসগুলো অ্যাপ অ্যাক্সেস রিস্ক ভারডিক্টে কোনো ক্যাপচারিং, কন্ট্রোলিং বা ওভারলে রেসপন্স দেবে না। আপনার অ্যাক্সেসিবিলিটি অ্যাপের জন্য একটি এনহ্যান্সড গুগল প্লে অ্যাক্সেসিবিলিটি রিভিউয়ের অনুরোধ করতে, অ্যাপটি গুগল প্লে-তে প্রকাশ করুন এবং নিশ্চিত করুন যে আপনার অ্যাপের ম্যানিফেস্টে isAccessibilityTool ফ্ল্যাগটি true সেট করা আছে, অথবা একটি রিভিউর জন্য অনুরোধ করুন ।
অ্যাপ অ্যাক্সেস ঝুঁকির রায়ের উদাহরণ
নিম্নলিখিত সারণিতে অ্যাপ অ্যাক্সেস ঝুঁকির রায়ের কিছু উদাহরণ এবং সেগুলোর অর্থ দেওয়া হলো (এই সারণিতে প্রতিটি সম্ভাব্য ফলাফল তালিকাভুক্ত করা হয়নি):
| অ্যাপ অ্যাক্সেস ঝুঁকির রায়ের প্রতিক্রিয়ার উদাহরণ | ব্যাখ্যা |
|---|---|
appsDetected:["KNOWN_INSTALLED"] | শুধুমাত্র সেই অ্যাপগুলোই ইনস্টল করা আছে যেগুলো গুগল প্লে দ্বারা স্বীকৃত অথবা ডিভাইস প্রস্তুতকারক কর্তৃক সিস্টেম পার্টিশনে আগে থেকেই লোড করা থাকে। এমন কোনো অ্যাপ চালু নেই যার ফলে ক্যাপচারিং, কন্ট্রোলিং বা ওভারলে সংক্রান্ত রায় দেওয়া সম্ভব হবে। |
appsDetected:["KNOWN_INSTALLED","UNKNOWN_INSTALLED","UNKNOWN_CAPTURING"] | গুগল প্লে থেকে অ্যাপ ইনস্টল করা হয় অথবা ডিভাইস প্রস্তুতকারক কর্তৃক সিস্টেম পার্টিশনে আগে থেকেই লোড করা থাকে। অন্যান্য অ্যাপ চালু আছে এবং সেগুলোর অনুমতি সক্রিয় করা আছে, যা স্ক্রিন দেখতে বা অন্যান্য ইনপুট ও আউটপুট ক্যাপচার করতে ব্যবহার করা যেতে পারে। |
appsDetected:["KNOWN_INSTALLED","KNOWN_CAPTURING","UNKNOWN_INSTALLED","UNKNOWN_CONTROLLING"] | চালু থাকা প্লে বা সিস্টেম অ্যাপগুলোর এমন অনুমতি সক্রিয় করা আছে, যা ব্যবহার করে স্ক্রিন দেখা বা অন্যান্য ইনপুট ও আউটপুট ক্যাপচার করা যেতে পারে। এছাড়াও অন্যান্য অ্যাপ চালু আছে যেগুলোর অনুমতি সক্রিয় করা আছে, যা ব্যবহার করে ডিভাইসটি নিয়ন্ত্রণ করা এবং আপনার অ্যাপের ইনপুটগুলো সরাসরি নিয়ন্ত্রণ করা যেতে পারে। |
appAccessRiskVerdict: {} | একটি প্রয়োজনীয় শর্ত পূরণ না হওয়ায় অ্যাপ অ্যাক্সেসের ঝুঁকি মূল্যায়ন করা হয়নি। উদাহরণস্বরূপ, ডিভাইসটি যথেষ্ট নির্ভরযোগ্য ছিল না। |
আপনার ঝুঁকির মাত্রার উপর নির্ভর করে, আপনি সিদ্ধান্ত নিতে পারেন যে এগিয়ে যাওয়ার জন্য কোন কোন সিদ্ধান্তের সংমিশ্রণ গ্রহণযোগ্য এবং কোন কোন সিদ্ধান্তের উপর আপনি ব্যবস্থা নিতে চান। নিম্নলিখিত কোড স্নিপেটটি এটি যাচাই করার একটি উদাহরণ তুলে ধরে যে, এমন কোনো অ্যাপ চলছে না যা স্ক্রিন ক্যাপচার করতে বা আপনার অ্যাপকে নিয়ন্ত্রণ করতে পারে:
কোটলিন
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! } }
জাভা
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! } }
অ্যাপ অ্যাক্সেস ঝুঁকির রায়গুলি সংশোধন করুন
আপনার ঝুঁকির মাত্রার উপর নির্ভর করে, ব্যবহারকারীকে কোনো অনুরোধ বা কাজ সম্পন্ন করতে দেওয়ার আগে আপনি কোন অ্যাপ অ্যাক্সেস ঝুঁকির রায়ের উপর ব্যবস্থা নিতে চান, তা স্থির করতে পারেন। অ্যাপ অ্যাক্সেস ঝুঁকির রায় পরীক্ষা করার পর ব্যবহারকারীকে দেখানোর জন্য কিছু ঐচ্ছিক গুগল প্লে প্রম্পট রয়েছে। আপনি CLOSE_UNKNOWN_ACCESS_RISK দেখিয়ে ব্যবহারকারীকে সেই অজানা অ্যাপগুলো বন্ধ করতে বলতে পারেন যেগুলো অ্যাপ অ্যাক্সেস ঝুঁকির রায়ের কারণ, অথবা আপনি CLOSE_ALL_ACCESS_RISK দেখিয়ে ব্যবহারকারীকে সেই সমস্ত অ্যাপ (জানা এবং অজানা) বন্ধ করতে বলতে পারেন যেগুলো অ্যাপ অ্যাক্সেস ঝুঁকির রায়ের কারণ।
প্লে প্রোটেক্ট রায়
একবার সক্রিয় করা হলে, Play Integrity API পেলোডের environmentDetails ফিল্ডে Play Protect ভারডিক্টটি থাকবে:
"environmentDetails": {
"playProtectVerdict": "NO_ISSUES"
}
playProtectVerdict নিম্নলিখিত মানগুলির মধ্যে যেকোনো একটি থাকতে পারে:
-
NO_ISSUES - প্লে প্রোটেক্ট চালু আছে এবং ডিভাইসটিতে কোনো অ্যাপ-সংক্রান্ত সমস্যা খুঁজে পাওয়া যায়নি।
-
NO_DATA - প্লে প্রোটেক্ট চালু আছে কিন্তু এখনও কোনো স্ক্যান করা হয়নি। ডিভাইসটি অথবা প্লে স্টোর অ্যাপটি সম্প্রতি রিসেট করা হয়ে থাকতে পারে।
-
POSSIBLE_RISK - প্লে প্রোটেক্ট বন্ধ করা আছে।
-
MEDIUM_RISK - প্লে প্রোটেক্ট চালু আছে এবং ডিভাইসটিতে সম্ভাব্য ক্ষতিকর অ্যাপ ইনস্টল করা আছে বলে শনাক্ত করেছে।
-
HIGH_RISK - প্লে প্রোটেক্ট চালু আছে এবং ডিভাইসটিতে বিপজ্জনক অ্যাপ ইনস্টল করা আছে বলে শনাক্ত করেছে।
-
UNEVALUATED প্লে প্রোটেক্ট রায়টি মূল্যায়ন করা হয়নি।
এটি বিভিন্ন কারণে ঘটতে পারে, যার মধ্যে নিম্নলিখিতগুলো অন্তর্ভুক্ত:
- ডিভাইসটি যথেষ্ট নির্ভরযোগ্য নয়।
- ব্যবহারকারী অ্যাকাউন্টটির কোনো প্লে লাইসেন্স নেই।
প্লে প্রোটেক্ট রায় ব্যবহারের নির্দেশিকা
আপনার ঝুঁকি সহনশীলতার উপর ভিত্তি করে, আপনার অ্যাপের ব্যাকএন্ড সার্ভার রায়ের ওপর নির্ভর করে কী পদক্ষেপ নেবে তা সিদ্ধান্ত নিতে পারে। এখানে কিছু পরামর্শ এবং ব্যবহারকারীর সম্ভাব্য করণীয় বিষয় দেওয়া হলো:
-
NO_ISSUES - প্লে প্রোটেক্ট চালু আছে এবং কোনো সমস্যা খুঁজে পায়নি, তাই ব্যবহারকারীর কোনো পদক্ষেপ নেওয়ার প্রয়োজন নেই।
-
POSSIBLE_RISKএবংNO_DATA - এই সিদ্ধান্তগুলো পাওয়ার সময়, ব্যবহারকারীকে পরীক্ষা করে দেখতে বলুন যে প্লে প্রোটেক্ট চালু আছে এবং একটি স্ক্যান সম্পন্ন করেছে।
NO_DATAশুধুমাত্র বিরল পরিস্থিতিতেই দেখা যাবে। -
MEDIUM_RISKএবংHIGH_RISK - আপনার ঝুঁকি সহনশীলতার উপর নির্ভর করে, আপনি ব্যবহারকারীকে প্লে প্রোটেক্ট চালু করতে এবং এর সতর্কবার্তাগুলোর উপর ব্যবস্থা নিতে বলতে পারেন। যদি ব্যবহারকারী এই শর্তগুলো পূরণ করতে না পারেন, তবে আপনি তাকে সার্ভারের কার্যক্রম থেকে ব্লক করে দিতে পারেন।