Bu sayfada, döndürülen bütünlük kararının nasıl yorumlanacağı ve bu kararla nasıl çalışılacağı açıklanmaktadır. Standart veya klasik API isteği göndermiş olmanıza bakılmaksızın bütünlük değerlendirmesi benzer içerikle aynı biçimde döndürülür. Bütünlük değerlendirmesi; cihazların, uygulamaların ve hesapların geçerliliği hakkında bilgi sunar. Uygulamanızın sunucusu, şifresi çözülmüş ve doğrulanmış bir karardaki yükü kullanarak uygulamanızda belirli bir işlem veya istekle ilgili izlenecek en iyi yolu belirleyebilir.
Döndürülen bütünlük değerlendirmesi biçimi
Yük, düz metin JSON biçimindedir ve geliştirici tarafından sağlanan bilgilerin yanı sıra bütünlük sinyallerini içerir.
Genel yük yapısı aşağıdaki gibidir:
{ "requestDetails": { ... }, "appIntegrity": { ... }, "deviceIntegrity": { ... }, "accountDetails": { ... }, "environmentDetails": { ... } }
Her bütünlük değerlendirmesini kontrol etmeden önce requestDetails alanındaki değerlerin orijinal istekteki değerlerle eşleştiğinden emin olmanız gerekir. Aşağıdaki bölümlerde her alan ayrıntılı olarak açıklanmıştır.
İstek ayrıntıları alanı
requestDetails alanı, istekle ilgili bilgileri içerir. Standart istekler için requestHash alanında, klasik istekler için de nonce alanında geliştirici tarafından sağlanan bilgiler buna dahildir.
Standart API istekleri için:
"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" }
Bu değerler, orijinal isteğin değerleriyle eşleşmelidir. Bu nedenle, aşağıdaki kod snippet'inde gösterildiği gibi, orijinal istekte gönderilenlerle eşleştiğinden emin olarak JSON yükünün requestDetails bölümünü doğrulayın:requestPackageNamerequestHash
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. ... }
Klasik API istekleri için:
"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" }
Bu değerler, orijinal isteğin değerleriyle eşleşmelidir. Bu nedenle, aşağıdaki kod snippet'inde gösterildiği gibi, orijinal istekte gönderilenlerle requestDetails ve nonce değerlerinin eşleştiğinden emin olarak JSON yükünün requestDetails bölümünü doğrulayın:requestPackageName
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. ... }
Uygulama bütünlüğü alanı
appIntegrity alanında paketle ilgili bilgiler yer alır.
"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 aşağıdaki değerleri alabilir:
PLAY_RECOGNIZED- Uygulama ve sertifika, Google Play tarafından dağıtılan sürümlerle eşleşiyor.
UNRECOGNIZED_VERSION- Sertifika veya paket adı, Google Play kayıtlarıyla eşleşmiyor.
UNEVALUATED- Uygulama bütünlüğü değerlendirilmemiştir. Koşullardan biri karşılanmamıştır (örneğin, cihaz yeterince güvenilir olmayabilir).
Jetonun sizin tarafınızdan oluşturulan bir uygulama tarafından oluşturulduğundan emin olmak için aşağıdaki kod snippet'inde gösterildiği gibi uygulama bütünlüğünün beklendiği gibi olduğunu doğrulayın:
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! }
Uygulama paket adını, uygulama sürümünü ve uygulama sertifikalarını manuel olarak da kontrol edebilirsiniz.
Cihaz bütünlüğü alanı
deviceIntegrity alanında, bir cihazın uygulama bütünlüğünü ne kadar iyi uygulayabildiğini gösteren bir veya daha fazla etiket içeren tek bir değer (
deviceRecognitionVerdict) bulunabilir. Cihaz hiçbir etiketin ölçütlerini karşılamıyorsa deviceIntegrity alanı deviceRecognitionVerdict değerini atlar.
"deviceIntegrity": { // "MEETS_DEVICE_INTEGRITY" is one of several possible values. "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"] }
Varsayılan olarak deviceRecognitionVerdict aşağıdakileri içerebilir:
MEETS_DEVICE_INTEGRITY- Uygulama, orijinal ve sertifikalı bir Android cihazda çalışıyor. Android 13 ve sonraki sürümlerde, cihaz bootloader'ının kilitli olduğuna ve yüklenen Android OS'nin sertifikalı bir cihaz üreticisi görüntüsü olduğuna dair donanım destekli kanıt bulunur.
- Boş (boş değer)
- Uygulamanın çalıştığı cihazda saldırı (API kancalama gibi) veya sistem bozulması (rootlanma gibi) belirtileri var ya da uygulama fiziksel bir cihazda çalışmıyor (örneğin, Google Play bütünlük kontrollerini geçmeyen bir emülatörde çalışıyor).
Jetonun güvenilir bir cihazdan geldiğinden emin olmak için aşağıdaki kod snippet'inde gösterildiği gibi deviceRecognitionVerdict değerinin beklendiği gibi olduğunu doğrulayın:
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! }
Test cihazınızın cihaz bütünlüğüyle ilgili sorun yaşıyorsanız fabrika ROM'unun yüklendiğinden (ör. cihazı sıfırlayarak) ve bootloader'ın kilitlendiğinden emin olun. Ayrıca Play Console'da Play Integrity API testleri oluşturabilirsiniz.
Koşullu cihaz etiketleri
Uygulamanız PC Üzerinde Google Play Games'de yayınlanıyorsa deviceRecognitionVerdict aşağıdaki etiketi de içerebilir:
MEETS_VIRTUAL_INTEGRITY- Uygulama, Google Play Hizmetleri'nin kullanıldığı Android destekli bir emülatörde çalışmaktadır. Emülatör, sistem bütünlüğü kontrollerini geçer ve temel Android uyumluluk şartlarını karşılar.
İsteğe bağlı cihaz bilgileri ve cihaz hatırlama
Katmanlı yaptırım stratejisinin bir parçası olarak isteğe bağlı cihaz etiketlerini almayı etkinleştirebilirsiniz. Bütünlük değerlendirmesinde ek etiketler almayı etkinleştirirseniz, deviceRecognitionVerdict aşağıdaki ek etiketleri içerebilir:
MEETS_BASIC_INTEGRITY- Uygulama, temel sistem bütünlüğü kontrollerini geçen bir cihazda çalışıyor.
Cihaz bootloader'ı kilitli veya kilidi açılmış olabilir ve başlatma durumu doğrulanmış veya doğrulanmamış olabilir. Cihaz sertifikalı olmayabilir. Bu durumda Google, güvenlik, gizlilik veya uygulama uyumluluğu konusunda herhangi bir garanti veremez. Android 13 ve sonraki sürümlerde,
MEETS_BASIC_INTEGRITYdeğerlendirmesi için yalnızca güven kökünün tasdikinin Google tarafından sağlanması gerekir. MEETS_STRONG_INTEGRITY- Uygulama, yakın zamanda güvenlik güncellemesi almış, orijinal ve sertifikalı bir Android cihazda çalışıyor.
- Android 13 ve sonraki sürümlerde
MEETS_STRONG_INTEGRITYkararı için Android OS bölümü yaması ve satıcı bölümü yaması da dahil olmak üzere cihazın tüm bölümleri için son bir yıldaMEETS_STRONG_INTEGRITYve güvenlik güncellemeleri yapılması gerekir.MEETS_DEVICE_INTEGRITY - Android 12 ve önceki sürümlerde
MEETS_STRONG_INTEGRITYkararı yalnızca donanım destekli başlatma bütünlüğü kanıtı gerektirir ve cihazın yakın zamanda güvenlik güncellemesi yapılmış olmasını gerekli kılmaz. Bu nedenle,MEETS_STRONG_INTEGRITYkullanılırkendeviceAttributesalanındaki Android SDK sürümünün de dikkate alınması önerilir.
- Android 13 ve sonraki sürümlerde
Etiketlerin her birinin ölçütleri karşılandığı takdirde tek bir cihaz, cihaz bütünlüğü kararında birden fazla cihaz etiketi döndürür.
Cihaz özellikleri
Cihazda çalışan Android OS'nin Android SDK sürümünü belirten cihaz özelliklerini de etkinleştirebilirsiniz. Android SDK sürümü, katmanlı yaptırım stratejisinin bir parçası olarak Android 13 ve sonraki sürümlerin yüklü olduğu cihazlarla daha düşük Android SDK sürümlerinin yüklü olduğu cihazları ayırt etmek için kullanışlıdır. Gelecekte diğer cihaz özellikleriyle genişletilebilir.
SDK sürümü değeri, Build.VERSION_CODES içinde tanımlanan Android SDK sürüm numarasıdır. Gerekli bir koşul karşılanmadığı takdirde SDK sürümü değerlendirilmez. Bu durumda, sdkVersion alanı ayarlanmamıştır. Bu nedenle, deviceAttributes alanı boştur.
Bunun nedeni aşağıdakilerden biri olabilir:
- Cihaz yeterince güvenilir değildir.
- Cihazda teknik sorunlar vardı.
deviceAttributes almayı etkinleştirirseniz deviceIntegrity alanında şu ek alan bulunur:
"deviceIntegrity": { "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"], "deviceAttributes": { // 33 is one possible value, which represents Android 13 (Tiramisu). "sdkVersion": 33 } }
SDK sürümü değerlendirilmezse deviceAttributes alanı şu şekilde ayarlanır:
"deviceIntegrity": { "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"], "deviceAttributes": {} // sdkVersion field is not set. }
Son cihaz etkinliği
Ayrıca, son cihaz etkinliğini de etkinleştirebilirsiniz. Bu özellik, uygulamanızın son bir saat içinde belirli bir cihazda kaç kez bütünlük jetonu istediğini belirtir. Uygulamanızı etkin bir saldırının göstergesi olabilecek beklenmedik hiperaktif cihazlara karşı korumak için son cihaz etkinliğini kullanabilirsiniz. Uygulamanızın, tipik bir cihaza yüklendiğinde her saat kaç kez bütünlük jetonu isteyeceğini tahmin ederek her bir son cihaz etkinliği düzeyine ne kadar güveneceğinize karar verebilirsiniz.
recentDeviceActivity alanını almayı etkinleştirirseniz deviceIntegrity alanında iki değer bulunur:
"deviceIntegrity": { "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"], "recentDeviceActivity": { // "LEVEL_2" is one of several possible values. "deviceActivityLevel": "LEVEL_2" } }
deviceActivityLevel tanımları modlar arasında farklılık gösterir ve aşağıdaki değerlerden birini alabilir:
| Son cihaz etkinliği düzeyi | Bu cihazda son bir saat içinde uygulama başına yapılan standart API bütünlük jetonu istekleri | Bu cihazda son bir saat içinde uygulama başına yapılan klasik API bütünlük jetonu istekleri |
|---|---|---|
LEVEL_1 (en düşük) |
10 veya daha az | 5 veya daha az |
LEVEL_2 |
11 ile 25 arasında | 6 ile 10 arasında |
LEVEL_3 |
26 ile 50 arasında | 11 ile 15 arasında |
LEVEL_4 (en yüksek) |
50'den fazla | 15'ten fazla |
UNEVALUATED |
Son cihaz etkinliği değerlendirilmedi. Bu durumun nedeni şunlar olabilir:
|
|
Cihaz geri çağırma (beta)
Ayrıca, cihaz hatırlama özelliğini etkinleştirebilirsiniz. Bu özellik, cihaz bazında bazı özel verileri belirli cihazlarda saklamanıza olanak tanır. Bu verileri, uygulamanız daha sonra aynı cihaza tekrar yüklendiğinde güvenilir bir şekilde alabilirsiniz. Bütünlük jetonu istedikten sonra, belirli bir cihaz için cihaz hatırlama değerlerini değiştirmek üzere ayrı bir sunucudan sunucuya çağrı yaparsınız.
deviceRecall'yı etkinleştirirseniz deviceIntegrity alanında, belirli cihaz için ayarladığınız cihaz hatırlama bilgileri yer alır:
"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 iki alana ayrılır:
values: Bu cihaz için daha önce ayarladığınız bit değerlerini geri çağırın.writeDates: Bit yazma tarihlerini yıl ve ay olarak UTC'ye göre doğru şekilde hatırlayın. Bir hatırlatma bitinin yazma tarihi, bit hertrueolarak ayarlandığında güncellenir ve bitfalseolarak ayarlandığında kaldırılır.
Cihaz hatırlama bilgileri kullanılamadığında cihaz hatırlama değeri boş olur:
"deviceIntegrity": {
"deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
"deviceRecall": {
"values": {},
"writeDates": {}
}
}
Hesap ayrıntıları alanı
accountDetails alanında, cihazda oturum açmış kullanıcı hesabı için uygulamanın Google Play lisanslama durumunu gösteren tek bir değer (appLicensingVerdict) bulunur. Kullanıcı hesabında uygulama için Play lisansı varsa kullanıcı, uygulamayı Google Play'den indirmiş veya satın almış demektir.
"accountDetails": { // This field can be LICENSED, UNLICENSED, or UNEVALUATED. "appLicensingVerdict": "LICENSED" }
appLicensingVerdict aşağıdaki değerlerden birine sahip olabilir:
LICENSED- Kullanıcının uygulamadan yararlanma hakkı bulunmaktadır. Yani kullanıcı, uygulamanızı Google Play'den cihazına yüklemiş veya güncellemiştir.
UNLICENSED- Kullanıcının uygulamadan yararlanma hakkı yoktur. Kullanıcının uygulamanızı başka cihazdan yüklediği veya Google Play dışında bir kanaldan edindiği durumlarda bu etiket görülür. Bunu düzeltmek için kullanıcılara GET_LICENSED iletişim kutusunu gösterebilirsiniz.
UNEVALUATEDKoşullardan biri karşılanmadığı için lisanslama ayrıntıları değerlendirilmemiştir.
Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:
- Cihaz yeterince güvenilir değildir.
- Cihazda uygulamanızın Google Play tarafından tanınmayan bir sürümü yüklüdür.
- Kullanıcı, Google Play'de oturum açmamıştır.
Kullanıcının uygulamanızdan yararlanma hakkına sahip olup olmadığını kontrol etmek için aşağıdaki kod snippet'inde gösterildiği gibi appLicensingVerdict değerinin beklendiği gibi olduğunu doğrulayın:
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! }
Ortam ayrıntıları alanı
Ortamla ilgili ek sinyalleri de etkinleştirebilirsiniz. Uygulama erişim riski; ekranı kaydetmek, yer paylaşımı görüntülemek veya cihazı kontrol etmek amacıyla başka uygulamaların çalıştırılıp çalıştırılmadığını uygulamanıza bildirir. Google Play Protect kararı, cihazda Google Play Protect'in etkinleştirilip etkinleştirilmediğini ve bilinen kötü amaçlı yazılım tespit edip etmediğini size bildirir.
Google Play Console'da uygulama erişimi riski kararı veya Play Protect kararını etkinleştirdiyseniz API yanıtınızda environmentDetails alanı bulunur. environmentDetails alanı iki değer içerebilir: appAccessRiskVerdict ve playProtectVerdict.
Uygulamaya erişim riski kararı
Etkinleştirildikten sonra Play Integrity API yükündeki environmentDetails alanında yeni uygulama erişim riski kararı görüntülenir.
{
"requestDetails": { ... },
"appIntegrity": { ... },
"deviceIntegrity": { ... },
"accountDetails": { ... },
"environmentDetails": {
"appAccessRiskVerdict": {
// This field contains one or more responses, for example the following.
"appsDetected": ["KNOWN_INSTALLED", "UNKNOWN_INSTALLED", "UNKNOWN_CAPTURING"]
}
}
}
Uygulama erişimi riski değerlendirildiyse appAccessRiskVerdict, bir veya daha fazla yanıt içeren appsDetected alanını içerir. Bu yanıtlar, algılanan uygulamaların yükleme kaynağına bağlı olarak aşağıdaki iki gruptan birine girer:
Play veya sistem uygulamaları: Google Play tarafından yüklenen veya cihaz üreticisi tarafından cihazın sistem bölümüne önceden yüklenen uygulamalar (
FLAG_SYSTEMile tanımlanır). Bu tür uygulamalarla ilgili yanıtların önüneKNOWN_eklenir.Diğer uygulamalar: Google Play tarafından yüklenmemiş uygulamalar. Bu, cihaz üreticisi tarafından sistem bölümüne önceden yüklenen uygulamaları kapsamaz. Bu tür uygulamaların yanıtlarının başına
UNKNOWN_eklenir.
Aşağıdaki yanıtlar döndürülebilir:
KNOWN_INSTALLED,UNKNOWN_INSTALLED- Yükleme kaynağıyla eşleşen uygulamalar yüklü olmalıdır.
KNOWN_CAPTURING,UNKNOWN_CAPTURING- Uygulamanız çalışırken ekranı görüntülemek için kullanılabilecek izinlerin etkinleştirildiği uygulamalar çalışıyor. Bu, cihazda çalışan ve Google Play tarafından bilinen doğrulanmış erişilebilirlik hizmetlerini hariç tutar.
KNOWN_CONTROLLING,UNKNOWN_CONTROLLING- Cihazı kontrol etmek ve uygulamanıza yapılan girişleri doğrudan kontrol etmek için kullanılabilecek, izinleri etkinleştirilmiş uygulamalar çalışıyor. Bu uygulamalar, uygulamanızın giriş ve çıkışlarını yakalamak için de kullanılabilir. Bu durum, cihazda çalışan ve Google Play tarafından doğrulanmış erişilebilirlik hizmetlerini kapsamaz.
KNOWN_OVERLAYS,UNKNOWN_OVERLAYS- Uygulamanızda yer paylaşımları göstermek için kullanılabilecek izinlerin etkinleştirildiği uygulamalar çalışıyor. Bu, cihazda çalışan ve Google Play tarafından bilinen doğrulanmış erişilebilirlik hizmetlerini kapsamaz.
- Boş (boş değer)
Gerekli bir koşul karşılanmadığı takdirde uygulama erişim riski değerlendirilmez. Bu durumda
appAccessRiskVerdictalanı boş. Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:- Cihaz yeterince güvenilir değildir.
- Cihazın form faktörü telefon, tablet veya katlanabilir cihaz değil.
- Cihazda Android 6 (API düzeyi 23) veya daha yeni bir sürüm çalışmıyordur.
- Cihazda uygulamanızın Google Play tarafından tanınmayan bir sürümü yüklüdür.
- Cihazdaki Google Play Store sürümü güncel değildir.
- Kullanıcı hesabında Play lisansı yok.
verdictOptOutparametresiyle standart bir istek kullanıldı.- Standart istekler için uygulama erişim riskini henüz desteklemeyen bir Play Integrity API kitaplığı sürümüyle standart istek kullanıldı.
Uygulama erişimi riski, geliştirilmiş bir Google Play erişilebilirlik incelemesinden geçmiş (cihazdaki herhangi bir uygulama mağazası tarafından yüklenmiş) doğrulanmış erişilebilirlik hizmetlerini otomatik olarak hariç tutar. "Hariç tutuldu", cihazda çalışan doğrulanmış erişilebilirlik hizmetlerinin, uygulama erişimi riski değerlendirmesinde yakalama, kontrol veya yer paylaşımı yanıtı döndürmeyeceği anlamına gelir. Erişilebilirlik uygulamanız için gelişmiş bir Google Play erişilebilirlik incelemesi talep etmek istiyorsanız uygulamayı Google Play'de yayınlayın. Uygulamanızın manifest dosyasında isAccessibilityTool işaretinin true olarak ayarlandığından emin olun veya inceleme isteğinde bulunun.
Uygulamaya erişim riski kararı örnekleri
Aşağıdaki tabloda, uygulama erişimi risk kararlarına ve bunların ne anlama geldiğine dair bazı örnekler verilmiştir (bu tabloda olası tüm sonuçlar listelenmemiştir):
| Örnek uygulama erişim riski kararı yanıtı | Yorumlama |
|---|---|
appsDetected:["KNOWN_INSTALLED"]
|
Yalnızca Google Play tarafından tanınan veya cihaz üreticisi tarafından sistem bölümüne önceden yüklenmiş uygulamalar yüklüdür. Kayıt, kontrol veya yer paylaşımı kararlarına neden olacak uygulamalar çalışmıyordur. |
appsDetected:["KNOWN_INSTALLED","UNKNOWN_INSTALLED","UNKNOWN_CAPTURING"]
|
Google Play tarafından yüklenen veya cihaz üreticisi tarafından sistem bölümüne önceden yüklenen uygulamalar vardır. Ekranı görüntülemek ya da diğer giriş ve çıkışları yakalamak için kullanılabilecek izinleri etkinleştirilmiş başka uygulamalar çalışıyordur. |
appsDetected:["KNOWN_INSTALLED","KNOWN_CAPTURING","UNKNOWN_INSTALLED","UNKNOWN_CONTROLLING"]
|
Ekranı görüntülemek veya diğer giriş ve çıkışları yakalamak için kullanılabilecek izinlerin etkinleştirildiği Play veya sistem uygulamaları çalışıyor. Cihazı kontrol etmek ve uygulamanıza doğrudan girişleri kontrol etmek için kullanılabilecek izinlerin etkinleştirildiği başka uygulamalar da çalışıyor. |
appAccessRiskVerdict: {}
|
Koşullardan biri karşılanmadığı için uygulama erişimi riski değerlendirilmemiştir. Örneğin, cihaz yeterince güvenilir olmayabilir. |
Risk düzeyinize bağlı olarak, devam etmek için hangi karar kombinasyonlarının kabul edilebilir olduğuna ve hangi kararlar için işlem yapmak istediğinize karar verebilirsiniz. Aşağıdaki kod snippet'inde, ekranı kaydedebilecek veya uygulamanızı kontrol edebilecek uygulamaların çalışmadığını doğrulama örneği gösterilmektedir:
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! } }
Uygulamaya erişim riski kararlarını düzeltme
Risk seviyenize bağlı olarak, kullanıcının bir isteği veya işlemi tamamlamasına izin vermeden önce hangi uygulama erişimi riski kararlarıyla ilgili işlem yapmak istediğinize karar verebilirsiniz. Uygulama erişim riski sonucunu kontrol ettikten sonra kullanıcıya gösterebileceğiniz isteğe bağlı Google Play istemleri vardır. Uygulama erişim riski kararına neden olan bilinmeyen uygulamaları kapatmasını istemek için kullanıcıya CLOSE_UNKNOWN_ACCESS_RISK'i gösterebilir veya uygulama erişim riski kararına neden olan tüm uygulamaları (bilinen ve bilinmeyen) kapatmasını istemek için kullanıcıya CLOSE_ALL_ACCESS_RISK'i gösterebilirsiniz.
Play Protect kararı
Etkinleştirildikten sonra Play Integrity API yükündeki environmentDetails alanında Google Play Protect kararı görüntülenir:
"environmentDetails": {
"playProtectVerdict": "NO_ISSUES"
}
playProtectVerdict aşağıdaki değerlerden birine sahip olabilir:
NO_ISSUES- Play Protect etkindir ve cihazda uygulama ile ilgili herhangi bir sorun tespit edilmemiştir.
NO_DATA- Play Protect etkindir ancak henüz tarama yapılmamıştır. Cihaz ya da Play Store uygulaması kısa süre önce sıfırlanmış olabilir.
POSSIBLE_RISK- Play Protect kapalıdır.
MEDIUM_RISK- Play Protect etkindir ve cihazda potansiyel zararlı uygulamaların yüklü olduğunu tespit etmiştir.
HIGH_RISK- Play Protect etkindir ve cihazda tehlikeli uygulamaların yüklü olduğunu tespit etmiştir.
UNEVALUATEDPlay Protect kararı değerlendirilmemiştir.
Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:
- Cihaz yeterince güvenilir değildir.
- Kullanıcı hesabında Play lisansı yok.
Play Protect kararını kullanma hakkında rehberlik
Uygulamanızın arka uç sunucusu, risk toleransınıza göre karara bağlı olarak nasıl davranacağına karar verebilir. Aşağıda bazı öneriler ve olası kullanıcı işlemleri verilmiştir:
NO_ISSUES- Play Protect etkin ve herhangi bir sorun tespit etmedi. Bu nedenle kullanıcıların herhangi bir işlem yapması gerekmiyor.
POSSIBLE_RISKveNO_DATA- Bu kararları aldığınızda kullanıcıdan Play Protect'in açık olup olmadığını ve tarama yapıp yapmadığını kontrol etmesini isteyin.
NO_DATAyalnızca nadir durumlarda görünmelidir. MEDIUM_RISKveHIGH_RISK- Risk toleransınıza bağlı olarak, kullanıcıdan Play Protect'i başlatmasını ve Play Protect uyarılarıyla ilgili işlem yapmasını isteyebilirsiniz. Kullanıcı bu şartları karşılayamıyorsa sunucu işlemine erişimini engelleyebilirsiniz.