Este artigo descreve como personalizar a proteção contra adulteração do Google Play para as suas apps e jogos. Para usar as funcionalidades de personalização descritas nesta página, tem de ter a proteção automática com a proteção contra adulteração ativada na Play Console.
Acerca da proteção contra adulteração personalizada
A proteção contra adulteração personalizada permite-lhe identificar métodos Java e Kotlin específicos na sua app que requerem uma segurança mais forte. Quando o lançamento é carregado para o Google Play, este dá prioridade à proteção melhorada para estes métodos específicos.
Ao identificar métodos para uma proteção melhorada, pode melhorar a defesa da sua app contra adulteração. Também pode usar a proteção de métodos para se proteger contra a exfiltração de segredos do cliente do seu binário (por exemplo, URLs ou chaves confidenciais que têm de ser incluídos no cliente).
Configure a proteção contra adulteração personalizada
Siga estes passos para implementar a proteção contra adulteração personalizada na base de código da sua app.
Passo 1: adicione a interface de proteção automática à sua base de código
Primeiro, adicione a interface de proteção à sua app ou jogo.
Kotlin:
package com.google.android.play.protections.annotations/**
* Descreve que um método é um candidato à proteção melhorada.
*
* <p>Esta anotação será removida automaticamente do código dex do seu
* bundle no momento em que o Google Play protege o seu bundle. Use-a apenas como
* uma anotação ao nível do método. Qualquer outra utilização (por exemplo, aceder à classe
* de forma reflexiva no tempo de execução) não é suportada.
*/
@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;
/**
* Descreve que um método é um candidato à proteção melhorada.
*
* <p>Esta anotação será removida automaticamente do código dex do seu
* bundle no momento em que o Google Play protege o seu bundle. Use-a apenas como
* uma anotação ao nível do método. Qualquer outra utilização (por exemplo, aceder à classe
* de forma reflexiva no tempo de execução) não é suportada.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PlayAutomaticIntegrityProtection {}
# Manter a classe de anotação e os respetivos membros.
-keep class com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection* { *; }
# Por predefinição, o ProGuard trata os atributos de anotação como opcionais e remove-os
# no passo de ocultação. Esta regra garante que são mantidos.
-keepattributes RuntimeVisibleAnnotations, AnnotationDefault
# Manter quaisquer métodos com a anotação, mas permitir que sejam ocultados.
-keepclassmembers,allowobfuscation class * {
@com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection *;
}
Passo 2: anote métodos para uma proteção personalizada
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection
@PlayAutomaticIntegrityProtection()
fun myMethod() {
// Corpo do método…
}
Java
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection;
@PlayAutomaticIntegrityProtection()
public void myMethod() {
// Corpo do método…
}Passo 3: (opcional) proteja segredos do lado do cliente
A proteção de métodos personalizada oculta o código diretamente no corpo do método anotado. Pode usar esta opção para proteger chaves da API confidenciais.
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");
}
Passo 4: (opcional) faça a gestão da sobrecarga de desempenho da proteção
Por predefinição, chamar um método protegido adiciona uma sobrecarga de vários milissegundos. Por conseguinte, não deve ser chamado em cenários sensíveis ao desempenho nem na thread principal.
Se precisar de proteger um método em que a execução rápida é necessária, está disponível um modo de proteção mais leve. Pode usar um atributo de anotação para optar por um acesso mais rápido (carregado no arranque), embora esta proteção correspondente não seja tão forte.
Kotlin:
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
fun callApi() {
api.connect("YOUR_API_KEY")
}
Java:
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
public static void callApi() {
api.connect("YOUR_API_KEY");
}
Para usar esta opção, adicione o atributo da interface ao corpo da definição da anotação original do passo 1:
// Atualização da definição da anotação Kotlin
public annotation class PlayAutomaticIntegrityProtection(
/**
* Se for verdadeiro, o método anotado é carregado no arranque. Se for falso, é
* carregado a pedido.
*
* <p>Para o carregamento a pedido, a chamada do método incorre numa penalização de
* desempenho. Para o carregamento de arranque, o método permanece desocultado na memória
* na duração total da app.
*/
val loadAtStartup: Boolean = false
) {}
Passo 5: teste a sua app
Práticas recomendadas para selecionar métodos
Uma seleção ponderada de métodos resulta numa proteção geral mais forte. Se cada novo lançamento tiver um método recentemente protegido, essa versão da app ou do jogo será mais resiliente a ataques.
Como regra geral, para evitar afetar o desempenho da sua app, selecione métodos de execução pouco frequente em vez de métodos de execução frequente. Para ter a máxima proteção, selecione métodos que:
- Sejam fundamentais para a aplicação (a app falharia se fossem removidos).
- Não sejam executados na thread principal/da IU.
- Sejam executados mais do que uma vez na duração total da app, mas não sejam executados num loop de execução frequente.
- Sejam não triviais (métodos que contêm código ou dados não triviais).
- Não sejam executados durante o arranque, se possível.
- Tenham sido introduzidos recentemente ou refatorados significativamente no lançamento.
- Não sejam métodos abstratos, métodos de interface nem construtores.
- Não usem a reflexão e não carreguem diretamente uma biblioteca nativa.
Remova a proteção personalizada
Se já não quiser proteger um método específico, pode simplesmente remover a anotação @PlayAutomaticIntegrityProtection().