Proguard로 안드로이드 소스코드 난독화
안드로이드 앱의 보안 중요성
안드로이드 앱을 빌드하면 aab || apk 파일로 만들어 진다. 이들은 단순히 우리가 작성한 코드들의 압축에 불과하다. 따라서 apk의 압축을 풀면 우리가 작성한 코드의 내부가 모두 보인다. 안드로이드 스튜디오에서 보면 아래와같이 모두 보이는것을 알 수 있다.
만약 이 상태로 앱을 출시한다면 앱의 리버스 엔지니어링이 가능하다는 뜻이며, 누군가 우리의 코드를 베껴 새로운 앱을 낼 수도 있다는 이야기이다.
따라서 우리는 우리의 앱 구조를 파악하지 못하게 할 장치가 필요하다.
💡 현재 Android Gradle Plugin(3.4.0+)에서는 ProGuard 대신 R8이 기본 코드 축소·난독화 도구다.
proguard-rules.pro에 작성한 규칙은 R8에서 그대로 동작한다.
난독화 적용 방법
zippu/android/app/build.gradle에 들어가서 buildTypes 확인
android {
...
buildTypes {
debug {
signingConfig signingConfigs.debug
minifyEnabled true
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
}
release {
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
}
}
...
}
shrinkResources
불필요한 리소스 제거. 파일 사이즈 감소.
minifyEnabled = true
클래스 명과 함수명들이 모두 a,b,c등으로 바뀌게 된다.
이로 인해 클래스명이나 함수명을 알 수 없게 되어 코드 구조 파악과 분석 비용을 크게 높인다. 다만 “거의 불가능”해지는 것은 아니다. 문자열 리터럴, API 엔드포인트, 리소스 등은 그대로 남고 jadx 같은 디컴파일러로 여전히 코드를 읽어낼 수 있다. 또한 minifyEnabled true는 난독화뿐 아니라 미사용 코드 제거(shrink)와 최적화(optimize)도 함께 수행하므로, 필요한 -keep 규칙이 빠지면 리플렉션으로 참조되는 클래스·메서드가 제거되어 런타임 크래시가 날 수 있다.
shrinkResources는 소스 난독화의 동작에 관여하는 속성이 아니라, 앱의 패키징 시 사용하지 않는 리소스를 자동으로 제거할지 말지를 결정하는 것이다. 단독으로는 동작하지 않으며 반드시 minifyEnabled true와 함께 사용해야 한다(코드 축소가 켜져 있어야 어떤 리소스가 미사용인지 판단할 수 있기 때문).
proguardFiles getDefaultProguardFile을 사용해서 기본 프로가드 설정
프로가드를 사용/미사용으로 설정
enableProguardInReleaseBuilds
코드 난독화에 필요한 proguard 활성화.
코드 난독화와 동시에 코드사이즈를 줄여주어 용량이 감소.
cd android && ./gradlew app:assembleRelease --stacktrace
예외처리
proguard
난독화가 되면 안되는 클래스들은 proguard에 정의해서 난독화 방지가 가능하다.
keep문 추가
(1) 패키지에 속한 모든 클래스와 함수들의 난독화 방지.
-keep class * extends com.google.gson.TypeAdapter
-keep class com.google.googlesignin.** { *; }
(2) interface 난독화 미처리
-keep interface *{
<methods>;
<fields>;
}
(3) 소스파일의 라인은 섞지 않음
섞으면 stacktrace에서 라인추적이 불가능.
-keepattributes SourceFile,LineNumberTable
(4) 스택 트레이스의 소스 파일명 문자열 치환
-renamesourcefileattribute SourceFile
-renamesourcefileattribute는 변수명과는 무관하다. 스택 트레이스에 기록되는 원본 소스 파일명 문자열을, 여기 지정한 이름(예: SourceFile)이라는 상수 문자열로 바꿔 실제 파일명이 노출되지 않게 한다.
@Keepannotation: 개별클래스의 난독화 방지
@Keep
data class KotlinWorld(val blogName: String)
참고 자료
R8을 이용해 안드로이드 앱을 최적화하고 코드 유출 방지하기 : minifyEnabled, shrinkResource, proguard
Android aab(앱 번들) 용량이 150MB가 넘을 때 해결법 (shrinkResources와 minifyEnabled를 쓰지않고)
React Native 보안편 소스코드 난독화 - Android
ProGuard를 통한 안드로이드 애플리케이션의 난독화
GitHub - lugg/react-native-config: Bring some 12 factor love to your mobile apps!