Android에서 시크릿 보호: 실제 프로덕션에서 실제로 작동하는 방법
발행: (2026년 1월 1일 오후 03:08 GMT+9)
5 min read
원문: Dev.to
Source: Dev.to
Introduction
Android 앱에서는 클라이언트 측에 진정한 비밀이 없습니다. APK는 디컴파일될 수 있고, 문자열이 추출되며, 메모리를 검사하고, 런타임 동작을 후킹할 수 있습니다. 앱을 신뢰할 수 있는 환경으로 취급하는 것은 보안이 취약한 소프트웨어를 가장 빠르게 배포하는 방법입니다. 실제 보안은 숨기는 것이 아니라 아키텍처에 달려 있습니다.
Why long‑lived secrets must never live on the device
- 영구적인 API 키나 인증서를 앱에 저장하면 쉽게 추출될 수 있습니다.
- 공격자가 장기 비밀을 입수하면 앱을 무한히 가장할 수 있습니다.
- 단기간에 만료되고 폐기 가능한 인증서를 설계하면 침해 시 영향을 제한할 수 있습니다.
Using short‑lived, scoped tokens instead of embedded keys
- 백엔드 서비스에서 보안 인증 흐름(예: OAuth 2.0, OpenID Connect)을 사용해 토큰을 획득합니다.
- 토큰은 제한된 수명(분~시간)과 최소 권한만을 갖도록 스코프를 지정해야 합니다.
- 리프레시 토큰을 사용해 새로운 액세스 토큰으로 교환함으로써 앱을 업데이트하지 않아도 토큰을 폐기할 수 있습니다.
Proper use of Android Keystore + AES/GCM for local encryption
- Android Keystore에 암호화 키를 저장하면 앱 프로세스 메모리와 격리됩니다.
- 로컬에 저장되는 민감한 데이터는 인증된 암호화 방식인 AES‑GCM을 사용해 보호합니다.
- 키는 필요할 때만 가져와서 짧은 컨텍스트 내에서 암호화/복호화를 수행합니다.
What’s deprecated (Jetpack Security Crypto) and what to use instead
androidx.security:security-crypto라이브러리의 오래된 API는 일부 사용 사례에서 더 이상 권장되지 않습니다.- 키 관리가 개선되고 Keystore와 통합된 최신
androidx.security:security-crypto:1.1.0-alpha03(또는 이후 버전)으로 전환합니다. - 마이그레이션 가이드를 따라
EncryptedSharedPreferences와EncryptedFile생성자를 최신 빌더 형태로 교체합니다.
Secure transport, integrity signals, and runtime hardening
- HTTPS를 TLS 1.2 이상으로 강제하고 인증서 핀닝을 적용해 중간자 공격을 방지합니다.
- 무결성 검사(예: SafetyNet, Play Integrity API)를 사용해 변조되거나 루팅된 기기를 감지합니다.
- 런타임 난독화(ProGuard/R8)와 코드 스플리팅을 적용해 리버스 엔지니어링 난이도를 높입니다.
Designing systems that survive compromise, not deny it
- 클라이언트가 침해될 수 있다고 가정하고, 모든 요청에 대해 서버‑사이드 검증을 수행합니다.
- 백엔드에서 속도 제한, 이상 탐지, 토큰 폐기 메커니즘을 구현합니다.
- 보안 관련 이벤트를 로그에 기록하고 의심스러운 활동을 모니터링합니다.
Conclusion
민감한 데이터, 결제, 인증 등을 다루는 Android 앱을 개발한다면, 이러한 실천 방안은 프로덕션 수준 보안을 위해 필수적입니다.