본문 바로가기

Android

[Android] 앱 배포하기03_ Proguard로 코드 난독화하기

 

 

🎲 코드 난독화가 뭐야?

코드 난독화란 소스 코드의 가독성을 줄여서 코드의 분석 및 역공학을 어렵게 만드는 기술입니다

 

코드의 기능적 동작은 변경하지 않으면서, 코드의 구조와 내용을 복잡하게 만들어 해커나 악의적인 사용자가 코드를 이해하거나 수정하는 것을 어렵게 만들어줍니다 !

 

즉, 한마디로 코드를 알아보기 어렵게 만든다는 거죠

 

난독화 도구로는 Proguard, R8, DexGuard 등이 있는데 저는 Proguard를 사용해서 난독화를 진행했습니다

 

 

 

 

 

🤔 왜 해야할까?

1. 보안 강화

- 애플리케이션의 내부 동작과 알고리즘을 숨겨 소스 코드의 취약점을 악용하거나 불법적으로 분석하는 것을 어렵게 만들어줍니다

 

2. 역공학 방지

- 역컴파일러를 사용하여 원래의 소스 코드를 재구성하기 어렵게 만들어줍니다

 

3. 저작권 보호

- 소프트웨어의 저작권을 보호하고, 코드가 무단으로 사용되거나 배포되는 것을 방지해줍니다

 

배포 시 난독화가 필수는 아니지만 열심히 만든 앱이 무단으로 사용되거나 해킹 당하는 일을 방지하려면 난독화를 진행하는 것이 좋겠죠 !?

 

 

 

 

 

 

😮 그렇다면 어떤 코드들을 난독화 해야 해?

무작정 모든 코드들을 난독화하면 안됩니다

 

서버와 통신하는 부분 (response, request data 명은 난독화되면 서버와 통신이 불가능), Firebase, KaKao Login 등 소셜 로그인, Retrofit 등 여기에 추가적으로 각자의 앱에서 필요한만큼 예외 처리를 해주어야 합니다

 

보통 서버와 통신하거나 소셜 로그인, 파이어베이스 이렇게 예외 처리를 많이 해주는데요 외부 라이브러리와 통신하는 부분까지 모두 난독화를 진행해버리면 통신할 때 해당 코드를 찾지못해 통신이 어려워지겠죠!

 

그리고 예외 처리에 해당하는 코드가 많을수록 난독화의 수준이 낮아지고, 반대로 예외 처리를 최소한으로 할수록 난독화의 수준이 높아집니다

 

저는 진행하면서 "필요한 만큼" 이라는 게 참 어려웠는데요

난독화를 진행하는 김에 난독화의 수준을 높게 진행하고 싶어서 위에서 말했던 부분들인 서버와 통신하는 부분, Firebase, Retrofit, 소셜 로그인, 그리고 디버깅을 위한 소스 파일 및 라인 정보 유지, Kotlin 특수 클래스 유지 정도를 예외처리로 넣어주었습니다 

 

 

# 소스 파일 및 라인 정보 유지
-keepattributes SourceFile,LineNumberTable


# 소스 파일의 변수명 변경
-renamesourcefileattribute SourceFile


# Firebase Cloud Messaging
-keep class com.google.firebase.** { *; }
-keep interface com.google.firebase.** { *; }


# Retrofit
-keep class retrofit2.** { *; }
-keep class com.squareup.retrofit2.** { *; }
-keep class okhttp3.** { *; }


# kakao login
-keep interface com.kakao.sdk.** { *; }


# 카카오 SDK 관련 클래스와 메서드를 난독화에서 제외
-keep class com.kakao.sdk.** { *; }
-keep class com.kakao.auth.** { *; }
-keep class com.kakao.network.** { *; }
-keep class com.kakao.util.** { *; }
-keep class com.kakao.util.helper.** { *; }
-keep class com.kakao.sdk.**.model.* { <fields>; }
-keep class * extends com.google.gson.TypeAdapter

-dontwarn org.bouncycastle.jsse.**
-dontwarn org.conscrypt.*
-dontwarn org.openjsse.**


# 서버 응답 데이터 필드 이름 난독화 예외 처리
-keep class com.umc.anddeul.**.model.** {
    <fields>;
}

-keep class com.umc.anddeul.alarm.DeviceTokenRequest {
    <fields>;
}


# Kotlin 특수 클래스 유지
-keepclassmembers class **$WhenMappings { <fields>; }
-keep class kotlin.Metadata { *; }
-keepclassmembers class kotlin.Metadata { public <methods>; }

 

 

 

 

 

🧩 제대로 난독화 되었는지 확인하기

이렇게 난독화를 진행하면 잘 작동했던 기존의 로직들이 동작하지 않거나 앱 내에서 Crash가 발생하여 앱이 종료되는 현상이 발생할 수 있기 때문에 꼭 다시 release build로 실행해보고 모든 기능이 제대로 돌아가는지 확인을 해주어야 합니다

 

그리고 추가적으로 직접 난독화된 코드를 확인해보고 싶다면 dex2jar, jd gui 등의 디컴파일 툴을 이용해 apk 파일을 디컴파일 해볼 수도 있습니다

 

apk 파일을 디컴파일 하는 방법을 따로 작성하진 않았지만 난독화된 apk 파일을 디컴파일 해보면 아래 이미지처럼 코드들이 난독화 되어있는 모습을 확인할 수 있습니다

 

 

 

 

 

 

 

🍀 마무리

실제로 회사에선 난독화가 선택 아닌 필수이기에 앱을 배포하는 김에 진행해보고 싶어서 진행해보았습니다

처음엔 빌드가 제대로 안될까봐 겁을 먹었는데 하나씩 테스트 해보니 그렇게 어려울 게 없던 것 같네요

 

"필요한 만큼" 예외 처리하는 게 가장 고민이였던 것 같습니다 ..ㅎㅎ

역시 정해지지 않은 답을 정하는 게 제일 어렵네요

 

난독화를 통해 안전한 앱 배포 합시다 '-' !