В этой статье рассказывается, как настроить защиту от вмешательства для приложений и игр в Google Play. Чтобы использовать описанные здесь функции, в Play Console должна быть включена автоматическая защита с защитой от вмешательства.
Что такое настраиваемая защита от вмешательства
Эта функция позволяет указать, для каких методов Java и Kotlin в вашем приложении требуется повышенный уровень безопасности. Когда вы загружаете выпуск в Google Play, улучшенная защита применяется для этих методов в первую очередь.
Определив такие методы, вы повысите устойчивость приложения к вмешательствам. Эту функцию также можно использовать, чтобы предотвратить утечку секретных кодов клиента из исполняемого файла, например конфиденциальных ключей или URL, которые должны добавляться в клиент.
Как настроить защиту от вмешательства
Чтобы реализовать в базе кода приложения настраиваемую защиту от вмешательства, сделайте следующее:
Шаг 1. Добавьте в базу кода интерфейс автоматической защиты
Вот как это сделать:
Kotlin
package com.google.android.play.protections.annotations/**
* Указывает, что для метода следует применять улучшенную защиту.
*
* <p>Когда Google Play задействует защиту,
* эта аннотация будет автоматически удалена из DEX-кода вашего набора. Используйте ее
* только на уровне метода. Она не подходит для других целей, например
* доступа к классу с помощью рефлексии.
*/
@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;
/**
* Указывает, что для метода следует применять улучшенную защиту.
*
* <p>Когда Google Play задействует защиту,
* эта аннотация будет автоматически удалена из DEX-кода вашего набора. Используйте ее
* только на уровне метода. Она не подходит для других целей, например
* доступа к классу с помощью рефлексии.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PlayAutomaticIntegrityProtection {}
# Сохранять класс аннотаций и его члены.
-keep class com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection* { *; }
# По умолчанию ProGuard считает атрибуты аннотаций необязательными и удаляет
# их на этапе обфускации. Благодаря этому правилу они сохранятся.
-keepattributes RuntimeVisibleAnnotations, AnnotationDefault
# Сохранять методы с аннотацией, но разрешить их обфускацию.
-keepclassmembers,allowobfuscation class * {
@com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection *;
}
Шаг 2. Укажите аннотации для методов, которые нужно защитить
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection
@PlayAutomaticIntegrityProtection()
fun myMethod() {
// Тело метода…
}
Java
import com.google.android.play.protections.annotations.PlayAutomaticIntegrityProtection;
@PlayAutomaticIntegrityProtection()
public void myMethod() {
// Тело метода…
}Шаг 3. Защитите секретные коды клиента (необязательно)
Настраиваемая защита методов позволяет обфусцировать (скрыть) код непосредственно в теле аннотированного метода. Так можно защитить конфиденциальные ключи API.
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");
}
Шаг 4. Настройте допустимую дополнительную нагрузку (необязательно)
По умолчанию вызов защищенного метода увеличивает время выполнения на несколько миллисекунд. Поэтому такие методы нельзя применять в основном потоке или ситуациях, когда нужна высокая производительность.
Чтобы защитить метод, который должен выполняться быстро, его можно загружать при запуске, используя атрибут аннотации. Однако в этом случае защита будет не такой надежной.
Kotlin
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
fun callApi() {
api.connect("YOUR_API_KEY")
}
Java
@PlayAutomaticIntegrityProtection(loadAtStartup = true)
public static void callApi() {
api.connect("YOUR_API_KEY");
}
Чтобы использовать этот атрибут, добавьте его в тело аннотации из шага 1:
// Обновленное определение аннотации Kotlin
public annotation class PlayAutomaticIntegrityProtection(
/**
* Если задано значение true, аннотированный метод загружается при запуске. Если указано значение false,
* он загружается по запросу.
*
* <p>Когда метод загружается по запросу, его вызов снижает
* производительность. Если метод загружается при запуске, он будет деобфусцирован в памяти
* на протяжении всего времени работы приложения.
*/
val loadAtStartup: Boolean = false
) {}
Шаг 5. Протестируйте приложение
Как выбрать методы
Чтобы обеспечить высокий уровень безопасности, тщательно выбирайте методы. Если в каждый новый выпуск добавлять защищенный метод, приложение или игра будут более устойчивы к атакам.
Как правило, чтобы не снижать производительность приложения, лучше выбирать методы, которые используются редко. Для максимальной защиты выбирайте методы, которые:
- Критически важны для приложения (без них оно не будет работать).
- Не выполняются в основном потоке или потоке UI.
- Выполняются несколько раз за время работы приложения, но не в цикле.
- Содержат нетривиальный код или данные.
- По возможности не выполняются при запуске.
- Добавлены недавно или значительно переработаны в выпуске.
- Не относятся к абстрактным методам, методам интерфейса или конструкторам.
- Не используют рефлексию и не загружают нативную библиотеку напрямую.
Как удалить настраиваемую защиту
Если вы больше не хотите защищать определенный метод, просто удалите аннотацию @PlayAutomaticIntegrityProtection().