Tento článek popisuje, jak přizpůsobit ochranu Play proti neoprávněné manipulaci pro aplikace a hry. Pokud chcete používat funkce přizpůsobení popsané na této stránce, musíte mít v Play Console zapnutou automatickou ochranu s ochranou proti neoprávněné manipulaci.
Přizpůsobitelná ochrana proti neoprávněné manipulaci
Přizpůsobená ochrana proti neoprávněné manipulaci umožňuje identifikovat konkrétní metody Java a Kotlin v aplikaci, které vyžadují silnější zabezpečení. Když vydání nahrajete na Google Play, upřednostní se vylepšená ochrana těchto konkrétních metod.
Identifikováním metod pro vylepšenou ochranu můžete zlepšit obranu aplikace proti neoprávněné manipulaci. Pomocí ochrany metod můžete také zabránit exfiltraci tajných klíčů klienta z binárního souboru (například citlivých klíčů nebo adres URL, které je nutné zahrnout v klientovi).
Nastavení přizpůsobené ochrany proti neoprávněné manipulaci
Pokud chcete do kódu aplikace implementovat přizpůsobenou ochranu proti neoprávněné manipulaci, postupujte podle následujících pokynů.
Krok 1: Přidání rozhraní automatické ochrany do kódové báze
Nejdříve do aplikace nebo hry přidejte rozhraní ochrany.
Kotlin:
package com.google.android.play.protections.annotations/**
* Popisuje, že metoda je kandidátem na vylepšenou ochranu.
*
* <p>Tato poznámka bude z kódu dex vašeho
* balíčku automaticky odstraněna v okamžiku, kdy Google Play váš balíček ochrání. Použijte ji pouze jako
* poznámku na úrovni metody. Žádné jiné použití (např. k reflektivnímu přístupu ke třídě
* za běhu) není podporováno.
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
public annotation class PlayAutomaticIntegrityProtection() {}
Java:
package com.google.android.play.protections.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Udává, že je metoda kandidátem na vylepšenou ochranu.
*
* <p>Až váš balíček Google Play ochrání, bude tato poznámka
* z kódu dex balíčku automaticky odstraněna. Používejte ji jen jako
* poznámku na úrovni metody. Žádné jiné použití (např. k reflektivnímu přístupu ke třídě
* za běhu) není podporováno.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PlayAutomaticIntegrityProtection {}
# Zachovat třídu poznámek a její členy.
-keep class com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection* { *; }
# ProGuard ve výchozím nastavení považuje atributy poznámek za volitelné a v kroku
# obfuskace je odstraňuje. Toto pravidlo zajistí, že zůstanou zachovány.
-keepattributes RuntimeVisibleAnnotations, AnnotationDefault
# Zachovat všechny metody s poznámkou, ale umožnit jejich obfuskaci.
-keepclassmembers,allowobfuscation class * {
@com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection *;
}
Krok 2: Opatření metod poznámkami pro přizpůsobenou ochranu
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection
@PlayAutomaticIntegrityProtection()
fun myMethod() {
// Method body...
}
Java
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection;
@PlayAutomaticIntegrityProtection()
public void myMethod() {
// Tělo metody...
}Krok 3: (Volitelné) Ochrana tajných klíčů na straně klienta
Vlastní ochrana metody zakrývá (skrývá) kód přímo v těle metody opatřené poznámkami. Můžete tak ochránit citlivé klíče rozhraní API.
Kotlin:
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection
@PlayAutomaticIntegrityProtection()
fun callApi() {
api.connect("KLIC_ROZHRANI_API")
}
Java:
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection;
@PlayAutomaticIntegrityProtection()
public static void callApi() {
api.connect("KLIC_ROZHRANI_API");
}
Krok 4: (Volitelné) Správa dopadu ochrany na výkon
Ve výchozím nastavení způsobuje volání chráněné metody prodlevu několika milisekund. Proto nesmí být volána v případech citlivých na výkon ani v hlavním vlákně.
Pokud potřebujete chránit metodu, která se musí spouštět rychle, je k dispozici odlehčený režim ochrany. Rychlejší přístup (načítání při spuštění) můžete aktivovat pomocí atributu poznámky, ale příslušná ochrana není tak silná.
Kotlin:
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
fun callApi() {
api.connect("KLIC_ROZHRANI_API")
}
Java:
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
public static void callApi() {
api.connect("KLIC_ROZHRANI_API");
}
Pokud chcete tuto funkci použít, přidejte do těla původní definice poznámky z kroku 1 atribut rozhraní:
// Aktualizace definice poznámky Kotlin
public annotation class PlayAutomaticIntegrityProtection(
/**
* Pokud je hodnota true, metoda s poznámkou se načte při spuštění. Pokud je false, bude
* se načítat na vyžádání.
*
* <p>Při načítání na vyžádání bude mít volání metody dopad
* na výkon. Při načítání při spuštění zůstane metoda v paměti deobfuskovaná
* po celou dobu životnosti aplikace.
*/
val loadAtStartup: Boolean = false
) {}
Krok 5: Otestování aplikace
Doporučené postupy pro výběr metod
Promyšlený výběr metod vede k silnější celkové ochraně. Pokud bude každé nové vydání obsahovat nově chráněnou metodu, bude daná verze aplikace nebo hry odolnější vůči útokům.
Obecně platí, že pokud chcete předejít dopadu na výkon aplikace, měli byste vybírat spíše studené metody než horké metody. Pro maximální ochranu vyberte metody, které:
- Jsou pro aplikaci kritické (aplikace by bez nich nefungovala).
- Nespouštějí se v hlavním vláknu ani ve vláknu uživatelského rozhraní.
- Spouštějí se během životního cyklu aplikace více než jednou, ale ne v horké smyčce.
- Nejsou triviální (metody obsahující netriviální kód nebo data).
- Nespouštějí se při spuštění aplikace nebo hry (pokud je to možné).
- Jsou ve vydání zavedeny nově nebo výrazně refaktorovány.
- Nejsou abstraktními metodami, metodami rozhraní ani konstruktory.
- Nepoužívají reflexi a nenačítají přímo nativní knihovnu.
Odstranění přizpůsobené ochrany
Pokud už konkrétní metodu chránit nechcete, můžete jednoduše odstranit poznámku @PlayAutomaticIntegrityProtection().