Cet article explique comment personnaliser la protection contre la falsification proposée par Play pour vos jeux et applications. Pour utiliser les fonctionnalités de personnalisation décrites sur cette page, vous devez avoir activé la protection automatique avec protection contre la falsification dans la Play Console.
À propos de la protection personnalisée contre la falsification
La protection personnalisée contre la falsification vous permet de désigner les méthodes Java et Kotlin spécifiques de votre application qui nécessitent une sécurité renforcée. Lorsque votre version est importée sur Play, Google Play donne la priorité à la protection renforcée de ces méthodes spécifiques.
Désigner les méthodes qui nécessitent une protection renforcée vous permet de mieux défendre votre application contre la falsification. Vous pouvez également utiliser la protection des méthodes pour vous prémunir contre l'exfiltration des codes secrets du client de votre binaire (par exemple, des clés ou des URL sensibles qui doivent être incluses dans le client).
Configurer la protection personnalisée contre la falsification
Suivez ces étapes pour implémenter une protection personnalisée contre la falsification dans le codebase de votre application.
Étape 1 : Ajoutez l'interface de protection automatique à votre codebase
Tout d'abord, ajoutez l'interface de protection à votre application ou à votre jeu.
Kotlin :
package com.google.android.play.protections.annotations/**
* Indique qu'une méthode doit recevoir une protection renforcée.
*
* <p>Cette annotation sera automatiquement supprimée du code dex de votre
* bundle au moment où Google Play protège votre bundle. Utilisez-la uniquement comme
* annotation au niveau de la méthode. Aucune autre utilisation (par exemple, l'accès à la classe
* de manière réflexive au moment de l'exécution) n'est acceptée.
*/
@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;
/**
* Indique qu'une méthode doit recevoir une protection renforcée.
*
* <p>Cette annotation sera automatiquement supprimée du code dex de votre
* bundle au moment où Google Play protège votre bundle. Utilisez-là uniquement comme
* annotation au niveau de la méthode. Aucune autre utilisation (par exemple, l'accès à la classe
* de manière réflexive au moment de l'exécution) n'est acceptée.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PlayAutomaticIntegrityProtection {}
# Conserver la classe de l'annotation et ses éléments.
-keep class com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection* { *; }
# Par défaut, ProGuard traite les attributs d'annotation comme facultatifs et les supprime
# lors de l'étape d'obscurcissement. Cette règle garantit qu'ils sont conservés.
-keepattributes RuntimeVisibleAnnotations, AnnotationDefault
# Conserver toute méthode avec l'annotation, mais autoriser son obscurcissement.
-keepclassmembers,allowobfuscation class * {
@com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection *;
}
Étape 2 : Annotez les méthodes pour la protection personnalisée
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection
@PlayAutomaticIntegrityProtection()
fun myMethod() {
// Corps de la méthode…
}
Java
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection;
@PlayAutomaticIntegrityProtection()
public void myMethod() {
// Corps de la méthode…
}Étape 3 : (Facultatif) Protégez les codes secrets côté client
La protection personnalisée des méthodes obscurcit (masque) le code directement dans le corps de la méthode annotée. Vous pouvez l'utiliser pour protéger les clés API sensibles.
Kotlin :
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection
@PlayAutomaticIntegrityProtection()
fun callApi() {
api.connect("YOUR_API_KEY")
}
Java :
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection;
@PlayAutomaticIntegrityProtection()
public static void callApi() {
api.connect("YOUR_API_KEY");
}
Étape 4 : (Facultatif) Gérez l'impact de la protection sur les performances
Par défaut, l'appel d'une méthode protégée ajoute un délai de plusieurs millisecondes. Par conséquent, elle ne doit pas être appelée dans des scénarios exigeant un certain niveau de performance ni sur le thread principal.
Si vous devez protéger une méthode nécessitant une exécution rapide, un mode de protection plus léger est disponible. Vous pouvez utiliser un attribut d'annotation pour accélérer l'accès (méthode chargée au démarrage), bien que la protection correspondante soit moins efficace.
Kotlin :
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
fun callApi() {
api.connect("YOUR_API_KEY")
}
Java :
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
public static void callApi() {
api.connect("YOUR_API_KEY");
}
Pour ce faire, ajoutez l'attribut d'interface au corps de la définition de votre annotation d'origine issue de l'étape 1 :
// Mise à jour de la définition de l'annotation Kotlin
public annotation class PlayAutomaticIntegrityProtection(
/**
* Si la valeur est "true", la méthode annotée sera chargée au démarrage. Si la valeur est "false", elle
* sera chargée à la demande.
*
* <p>Pour le chargement à la demande, l'appel de la méthode entraîne une perte
* de performances. Pour le chargement au démarrage, la méthode restera désobscurcie en mémoire
* pendant toute la durée de vie de l'application.
*/
val loadAtStartup: Boolean = false
) {}
Étape 5 : Testez votre application
Bonnes pratiques de sélection des méthodes
Sélectionnez les méthodes de manière judicieuse pour bénéficier d'une meilleure protection globale. Si chaque nouvelle version comporte une méthode qui vient d'être protégée, cette version de l'application ou du jeu sera plus résistante aux attaques.
En règle générale, pour éviter d'amoindrir les performances de votre application, sélectionnez des méthodes "froides" (exécutées occasionnellement) plutôt que "chaudes" (exécutées fréquemment). Pour bénéficier d'une protection maximale, sélectionnez des méthodes qui :
- sont essentielles à l'application (l'application ne fonctionnerait pas si elles étaient supprimées) ;
- ne sont pas exécutées dans le thread principal/thread UI ;
- s'exécutent plusieurs fois pendant la durée de vie de l'application, mais pas dans une boucle "chaude" ;
- sont non triviales (méthodes contenant des données ou du code non triviaux) ;
- ne sont pas exécutées au démarrage, si possible ;
- viennent d'être introduites ou ont été fortement refactorisées dans la version ;
- ne sont pas des méthodes abstraites, des méthodes d'interface ni des constructeurs ;
- n'utilisent pas la réflexion et ne chargent pas directement une bibliothèque native.
Supprimer la protection personnalisée
Si vous ne souhaitez plus protéger une méthode spécifique, il vous suffit de supprimer l'annotation @PlayAutomaticIntegrityProtection().