این صفحه درخواستهای استاندارد API را برای احکام یکپارچگی، که در Android نسخه 5.0 (سطح API 21) یا بالاتر پشتیبانی میشوند، شرح میدهد. هر زمان که برنامه شما در حال برقراری تماس با سرور برای بررسی واقعی بودن این تعامل است، میتوانید یک درخواست استاندارد API برای حکم یکپارچگی ارائه دهید.
نمای کلی
یک درخواست استاندارد از دو بخش تشکیل شده است:
- ارائهدهنده توکن یکپارچگی را آماده کنید (یکبار) : باید با یکپارچگی API تماس بگیرید تا ارائهدهنده توکن یکپارچگی را به خوبی آماده کنید قبل از اینکه بخواهید حکم یکپارچگی را دریافت کنید. برای مثال، میتوانید این کار را زمانی که برنامهتان راهاندازی میشود یا در پسزمینه قبل از نیاز به حکم یکپارچگی انجام دهید.
- درخواست یک توکن یکپارچگی (در صورت تقاضا) : هر زمان که برنامه شما درخواستی از سرور ارائه میکند که میخواهید بررسی کنید واقعی است، شما یک توکن یکپارچگی درخواست میکنید و آن را برای رمزگشایی و تأیید به سرور پشتیبان برنامه خود ارسال میکنید. سپس سرور باطن شما می تواند تصمیم بگیرد که چگونه عمل کند.
ارائه دهنده توکن یکپارچگی را آماده کنید (یک بار):
- برنامه شما با ارائهدهنده رمز یکپارچگی با شماره پروژه Google Cloud شما تماس میگیرد.
- برنامه شما ارائهدهنده توکن یکپارچگی را برای تماسهای بررسی گواهی بیشتر در حافظه نگه میدارد.
درخواست یک توکن یکپارچگی (در صورت تقاضا):
- برای اقدام کاربر که باید محافظت شود، برنامه شما هش (با استفاده از هر الگوریتم هش مناسب مانند SHA256) درخواستی را که باید انجام شود محاسبه میکند.
- برنامه شما یک توکن یکپارچگی درخواست میکند و هش درخواست را ارسال میکند.
- برنامه شما کد یکپارچگی امضا شده و رمزگذاری شده را از Play Integrity API دریافت می کند.
- برنامه شما رمز یکپارچگی را به باطن برنامه شما ارسال می کند.
- پشتیبان برنامه شما رمز را به سرور Google Play می فرستد. سرور Google Play حکم را رمزگشایی و تأیید می کند و نتایج را به باطن برنامه شما برمی گرداند.
- باطن برنامه شما بر اساس سیگنالهای موجود در بار توکن تصمیم میگیرد که چگونه ادامه دهد.
- پشتیبان برنامه شما نتایج تصمیم را به برنامه شما ارسال می کند.
ارائه دهنده توکن یکپارچگی را آماده کنید (یکبار)
قبل از اینکه یک درخواست استاندارد برای حکم یکپارچگی از Google Play ارائه دهید، باید ارائهدهنده توکن یکپارچگی را آماده کنید (یا "گرم کنید"). این به Google Play اجازه میدهد تا بهصورت هوشمندانه اطلاعات گواهی بخشی را در دستگاه ذخیره کند تا زمان تأخیر در مسیر بحرانی هنگام درخواست حکم یکپارچگی کاهش یابد. آمادهسازی مجدد ارائهدهنده توکن راهی برای تکرار بررسیهای یکپارچگی با منابع کمتر است که حکم یکپارچگی بعدی را که درخواست میکنید بیشتر بهروز میکند.
میتوانید ارائهدهنده توکن یکپارچگی را آماده کنید:
- هنگامی که برنامه شما راه اندازی می شود (یعنی هنگام راه اندازی سرد). آمادهسازی ارائهدهنده توکن ناهمزمان است و بنابراین تأثیری بر زمان راهاندازی نخواهد داشت. اگر قصد دارید در مدت کوتاهی پس از راهاندازی برنامه، یک درخواست حکم یکپارچگی ارائه دهید، این گزینه به خوبی کار میکند، برای مثال زمانی که یک کاربر وارد سیستم میشود یا بازیکنی به یک بازی میپیوندد.
- هنگامی که برنامه شما باز می شود (یعنی هنگام راه اندازی گرم). با این حال، توجه داشته باشید که هر نمونه برنامه فقط می تواند تا 5 بار در دقیقه توکن یکپارچگی را آماده کند.
- در هر زمانی در پسزمینه که میخواهید توکن را قبل از درخواست حکم یکپارچگی آماده کنید.
برای آماده سازی ارائه دهنده توکن یکپارچگی موارد زیر را انجام دهید:
- همانطور که در مثال های زیر نشان داده شده است، یک
StandardIntegrityManager
ایجاد کنید. - یک
PrepareIntegrityTokenRequest
بسازید و شماره پروژه Google Cloud را از طریق متدsetCloudProjectNumber()
تهیه کنید. - از مدیر برای فراخوانی
prepareIntegrityToken()
استفاده کنید وPrepareIntegrityTokenRequest
را ارائه کنید.
جاوا
import com.google.android.gms.tasks.Task; // Create an instance of a manager. StandardIntegrityManager standardIntegrityManager = IntegrityManagerFactory.createStandard(applicationContext); StandardIntegrityTokenProvider integrityTokenProvider; long cloudProjectNumber = ...; // Prepare integrity token. Can be called once in a while to keep internal // state fresh. standardIntegrityManager.prepareIntegrityToken( PrepareIntegrityTokenRequest.builder() .setCloudProjectNumber(cloudProjectNumber) .build()) .addOnSuccessListener(tokenProvider -> { integrityTokenProvider = tokenProvider; }) .addOnFailureListener(exception -> handleError(exception));
وحدت
IEnumerator PrepareIntegrityTokenCoroutine() { long cloudProjectNumber = ...; // Create an instance of a standard integrity manager. var standardIntegrityManager = new StandardIntegrityManager(); // Request the token provider. var integrityTokenProviderOperation = standardIntegrityManager.PrepareIntegrityToken( new PrepareIntegrityTokenRequest(cloudProjectNumber)); // Wait for PlayAsyncOperation to complete. yield return integrityTokenProviderOperation; // Check the resulting error code. if (integrityTokenProviderOperation.Error != StandardIntegrityErrorCode.NoError) { AppendStatusLog("StandardIntegrityAsyncOperation failed with error: " + integrityTokenProviderOperation.Error); yield break; } // Get the response. var integrityTokenProvider = integrityTokenProviderOperation.GetResult(); }
بومی
/// Initialize StandardIntegrityManager StandardIntegrityManager_init(/* app's java vm */, /* an android context */); /// Create a PrepareIntegrityTokenRequest opaque object. int64_t cloudProjectNumber = ...; PrepareIntegrityTokenRequest* tokenProviderRequest; PrepareIntegrityTokenRequest_create(&tokenProviderRequest); PrepareIntegrityTokenRequest_setCloudProjectNumber(tokenProviderRequest, cloudProjectNumber); /// Prepare a StandardIntegrityTokenProvider opaque type pointer and call /// StandardIntegrityManager_prepareIntegrityToken(). StandardIntegrityTokenProvider* tokenProvider; StandardIntegrityErrorCode error_code = StandardIntegrityManager_prepareIntegrityToken(tokenProviderRequest, &tokenProvider); /// ... /// Proceed to polling iff error_code == STANDARD_INTEGRITY_NO_ERROR if (error_code != STANDARD_INTEGRITY_NO_ERROR) { /// Remember to call the *_destroy() functions. return; } /// ... /// Use polling to wait for the async operation to complete. IntegrityResponseStatus token_provider_status; /// Check for error codes. StandardIntegrityErrorCode error_code = StandardIntegrityTokenProvider_getStatus(tokenProvider, &token_provider_status); if (error_code == STANDARD_INTEGRITY_NO_ERROR && token_provider_status == INTEGRITY_RESPONSE_COMPLETED) { /// continue to request token from the token provider } /// ... /// Remember to free up resources. PrepareIntegrityTokenRequest_destroy(tokenProviderRequest);
محافظت از درخواست ها در برابر دستکاری (توصیه می شود)
وقتی در حال بررسی یک عملکرد کاربر در برنامه خود با Play Integrity API هستید، میتوانید از فیلد requestHash
برای کاهش حملات دستکاری استفاده کنید. به عنوان مثال، ممکن است یک بازی بخواهد امتیاز بازیکن را به سرور باطن بازی گزارش کند و سرور شما میخواهد مطمئن شود که این امتیاز توسط یک سرور پراکسی دستکاری نشده است. Play Integrity API مقداری را که در قسمت requestHash
تنظیم کردهاید، در داخل پاسخ یکپارچگی امضا شده برمیگرداند. بدون requestHash
، توکن یکپارچگی فقط به دستگاه محدود می شود، اما نه به درخواست خاص، که امکان حمله را باز می کند. دستورالعمل های زیر نحوه استفاده موثر از فیلد requestHash
را شرح می دهد:
هنگامی که شما درخواست حکم یکپارچگی می کنید:
- خلاصه ای از تمام پارامترهای درخواست مربوطه (به عنوان مثال SHA256 یک سریال سازی درخواست پایدار) را از اقدام کاربر یا درخواست سرور که در حال انجام است، محاسبه کنید. مقدار تنظیم شده در قسمت
requestHash
حداکثر 500 بایت طول دارد. هر گونه داده درخواست برنامه را درrequestHash
وارد کنید که بسیار مهم یا مرتبط با اقدامی است که در حال بررسی یا محافظت از آن هستید. فیلدrequestHash
به کلمه در توکن یکپارچگی گنجانده شده است، بنابراین مقادیر طولانی ممکن است اندازه درخواست را افزایش دهند. - خلاصه را به عنوان فیلد
requestHash
در Play Integrity API ارائه دهید و رمز یکپارچگی را دریافت کنید.
هنگامی که یک حکم صداقت دریافت می کنید:
- رمز یکپارچگی را رمزگشایی کنید و فیلد
requestHash
را استخراج کنید. - خلاصه درخواست را به همان روشی که در برنامه وجود دارد محاسبه کنید (مثلاً SHA256 یک سریال درخواست پایدار).
- خلاصه های سمت برنامه و سمت سرور را مقایسه کنید. اگر مطابقت نداشته باشند، درخواست قابل اعتماد نیست.
درخواست حکم صداقت (در صورت تقاضا)
پس از آمادهسازی ارائهدهنده توکن یکپارچگی، میتوانید درخواست احکام یکپارچگی را از Google Play آغاز کنید. برای این کار مراحل زیر را انجام دهید:
- همانطور که در بالا نشان داده شده است، یک
StandardIntegrityTokenProvider
دریافت کنید. - یک
StandardIntegrityTokenRequest
بسازید و هش درخواست اکشن کاربری را که میخواهید از طریق متدsetRequestHash
محافظت کنید، تهیه کنید. - از ارائهدهنده توکن یکپارچگی برای فراخوانی
request()
استفاده کنید کهStandardIntegrityTokenRequest
را ارائه میکند.
جاوا
import com.google.android.gms.tasks.Task; StandardIntegrityTokenProvider integrityTokenProvider; // See above how to prepare integrityTokenProvider. // Request integrity token by providing a user action request hash. Can be called // several times for different user actions. String requestHash = "2cp24z..."; Task<StandardIntegrityToken> integrityTokenResponse = integrityTokenProvider.request( StandardIntegrityTokenRequest.builder() .setRequestHash(requestHash) .build()); integrityTokenResponse .addOnSuccessListener(response -> sendToServer(response.token())) .addOnFailureListener(exception -> handleError(exception));
وحدت
IEnumerator RequestIntegrityTokenCoroutine() { StandardIntegrityTokenProvider integrityTokenProvider; // See above how to prepare integrityTokenProvider. // Request integrity token by providing a user action request hash. Can be called // several times for different user actions. String requestHash = "2cp24z..."; var integrityTokenOperation = integrityTokenProvider.Request( new StandardIntegrityTokenRequest(requestHash) ); // Wait for PlayAsyncOperation to complete. yield return integrityTokenOperation; // Check the resulting error code. if (integrityTokenOperation.Error != StandardIntegrityErrorCode.NoError) { AppendStatusLog("StandardIntegrityAsyncOperation failed with error: " + integrityTokenOperation.Error); yield break; } // Get the response. var integrityToken = integrityTokenOperation.GetResult(); }
بومی
/// Create a StandardIntegrityTokenRequest opaque object. const char* requestHash = ...; StandardIntegrityTokenRequest* tokenRequest; StandardIntegrityTokenRequest_create(&tokenRequest); StandardIntegrityTokenRequest_setRequestHash(tokenRequest, requestHash); /// Prepare a StandardIntegrityToken opaque type pointer and call /// StandardIntegrityTokenProvider_request(). Can be called several times for /// different user actions. See above how to prepare token provider. StandardIntegrityToken* token; StandardIntegrityErrorCode error_code = StandardIntegrityTokenProvider_request(tokenProvider, tokenRequest, &token); /// ... /// Proceed to polling iff error_code == STANDARD_INTEGRITY_NO_ERROR if (error_code != STANDARD_INTEGRITY_NO_ERROR) { /// Remember to call the *_destroy() functions. return; } /// ... /// Use polling to wait for the async operation to complete. IntegrityResponseStatus token_status; /// Check for error codes. StandardIntegrityErrorCode error_code = StandardIntegrityToken_getStatus(token, &token_status); if (error_code == STANDARD_INTEGRITY_NO_ERROR && token_status == INTEGRITY_RESPONSE_COMPLETED) { const char* integrityToken = StandardIntegrityToken_getToken(token); } /// ... /// Remember to free up resources. StandardIntegrityTokenRequest_destroy(tokenRequest); StandardIntegrityToken_destroy(token); StandardIntegrityTokenProvider_destroy(tokenProvider); StandardIntegrityManager_destroy();
رای یکپارچگی را رمزگشایی و تأیید کنید
پس از درخواست حکم یکپارچگی، Play Integrity API یک رمز پاسخ رمزگذاری شده ارائه می دهد. برای به دست آوردن احکام یکپارچگی دستگاه، باید رمز یکپارچگی را در سرورهای Google رمزگشایی کنید. برای انجام این کار، این مراحل را کامل کنید:
- یک حساب سرویس در پروژه Google Cloud ایجاد کنید که به برنامه شما مرتبط است.
در سرور برنامه خود، رمز دسترسی را از اعتبار حساب سرویس خود با استفاده از محدوده playintegrity دریافت کنید و درخواست زیر را انجام دهید:
playintegrity.googleapis.com/v1/PACKAGE_NAME:decodeIntegrityToken -d \ '{ "integrity_token": "INTEGRITY_TOKEN" }'
پاسخ JSON را بخوانید.
محموله به دست آمده یک نشانه متن ساده است که حاوی احکام یکپارچگی است.
حفاظت از پخش خودکار
برای کاهش حملات پخش مجدد، Google Play به طور خودکار تضمین می کند که هر توکن یکپارچگی نمی تواند بارها مورد استفاده مجدد قرار گیرد. تلاش برای رمزگشایی مکرر همان نشانه منجر به احکام خالی می شود.