Как защититься от реверс-инжиниринга приложения
Что проверяют
Понимаете ли вы, что APK целиком у атакующего и полной защиты не бывает, бывает только повышение стоимости атаки. Следом почти всегда спрашивают, где хранить API-ключ и как сервер отличит ваше приложение от пересобранного.
Как отвечать
Разложите ответ по слоям:
- R8: в релизе при
isMinifyEnabled = trueудаляет неиспользуемый код, переименовывает классы и методы, оптимизирует байткод. Это переименование, а не шифрование: строки, ресурсы и логика в jadx читаются. Для классов, которые идут через рефлексию или сериализацию, нужны правила-keepвproguard-rules.pro; - секреты: ключ в
BuildConfig,strings.xmlили нативной.soизвлекается за минуты. Секретов в клиенте быть не должно: ключи сторонних API живут на бэкенде, приложение получает короткоживущие токены; - ключи на устройстве: генерируйте в Android Keystore, там они неэкспортируемые, а на поддерживающих устройствах хранятся в защищённом железе;
- целостность: Play Integrity API (заменил SafetyNet Attestation) даёт вердикт о приложении и устройстве. Проверять его нужно на сервере. На устройствах без сервисов Google он недоступен, для российской аудитории это важно;
- трафик: certificate pinning через Network Security Config или
CertificatePinnerв OkHttp мешает читать запросы через прокси, но заранее продумайте ротацию пинов; - отладка:
android:debuggableвыключен в релизе, проверки на root,Debug.isDebuggerConnected(), признаки Frida. Это поднимает порог, не больше; - логика: всё, от чего зависят деньги и права доступа, выполняется и проверяется на сервере.
Где спотыкаются
Считают, что R8 или NDK прячут ключ. Строку в нативной библиотеке находит утилита strings, в Java-коде её видно через jadx.
Делают проверки только на клиенте: isRooted() возвращает false после одного хука Frida. Решение должно приниматься на сервере по вердикту аттестации.
Перегибают с защитой. Обфускация без -keep ломает парсинг моделей в Gson, а жёсткая блокировка root отрезает легитимных пользователей и не останавливает атакующего.