헬스케어 스타트업은 보안 모바일 워크플로우를 설계하는 데 몇 달을 쓸 수 있지만, 그러고 나서 탈옥된 테스터의 폰에서 스크린샷과 로컬 캐시를 통해 환자 기록이 노출된 것을 발견할 수 있습니다. 동시에, 팀의 Electron 관리 패널 디버그 빌드에는 API 키가 번들에 포함된 채 배포될 수도 있습니다. 두 사례 모두 암호화와 관련 있지만, 암호화 라이브러리 하나를 추가한다고 해결되는 문제는 아닙니다.
앱 암호화는 일련의 의사결정 과정입니다. 팀은 데이터가 저장될 때 어떻게 보호되는지, 시스템 간에 어떻게 이동하는지, 키가 어디에 있는지, 공격자가 앱 패키지에서 무엇을 알아낼 수 있는지, 런타임이 변조에 어떻게 대응하는지, 서명된 업데이트가 이러한 보장을 어떻게 유지하는지 결정해야 합니다. 유용한 시작점은 Capacitor 앱을 위한 OTA 보안 체크리스트 민감 데이터, 신뢰 경계, 클라이언트 기능, 예상되는 악용 경로를 매핑하는 것입니다.
모바일 및 크로스 플랫폼 애플리케이션은 유난히 노출되기 쉬운 환경에 놓여 있습니다. 기기는 사무실을 벗어나고, 빌드는 복제되거나 사이드로딩될 수 있으며, 로컬 파일이 들여다보일 수 있고, 리버스 엔지니어링 도구도 어디서나 구할 수 있습니다. 아래 섹션에서는 스토리지와 전송부터 플랫폼 키 보호, 클라이언트 측 비밀 유지, 컴플라이언스, 릴리스 운영까지 단계별로 모델을 구축합니다.
목차
- 앱 암호화가 그 어느 때보다 중요한 이유
- 저장 시 암호화 vs 전송 중 암호화
- 앱 내 Code, 데이터, 시크릿 보호
- iOS, Android, Capacitor, Electron 플랫폼별 고려 사항
- 키 관리와 클라이언트 측 보안의 한계
- 규제 및 컴플라이언스 영향
- 흔한 실수와 보안 강화 베스트 프랙티스
- 암호화 계획에 모두 통합하기
앱 암호화가 그 어느 때보다 중요한 이유
일반적인 웹 애플리케이션은 민감한 로직과 비밀 정보를 조직이 제어하는 인프라에 보관합니다. 반면 모바일 애플리케이션은 code, 에셋, 설정 및 데이터 처리 로직을 타인의 기기로 전송합니다. Electron 애플리케이션도 유사한 문제를 겪는데, 애플리케이션을 실행하는 사용자가 JavaScript, 리소스 및 패키징된 파일을 검사할 수 있기 때문입니다.
이는 보안 경계(security boundary)를 변화시킵니다. 클라이언트는 유용하지만, 금고(vault)는 아닙니다. 암호화는 단순한 검사로부터 정보를 보호하고 탈취된 파일의 활용도를 낮출 수 있지만, 앱은 결국 어느 시점에 평문(plaintext)에 접근해야 합니다. 기기를 제어하는 공격자는 입력을 관찰하거나, 메모리를 조사하고, API를 인스트루먼트하거나, 실행 흐름을 수정할 수 있습니다.
의료 분야의 사례를 들어보겠습니다. 데이터베이스를 암호화하면 디스크에서 복사된 레코드는 보호할 수 있지만, 런타임이 탈취되었을 때 악성 프로세스에 복호화된 레코드가 노출되는 것까지 막지는 못합니다. 네트워크 트래픽을 암호화하면 백엔드로 전송되는 의료진의 요청은 보호할 수 있지만, 앱이 보호되지 않은 캐시에 저장한 로컬 내보내기 파일은 보호할 수 없습니다. 또한, 애플리케이션이 반드시 사용해야 하는 키가 난독화된 JavaScript에 숨겨져 있다면 결국 복구될 수밖에 없습니다.
실무 원칙: 모든 클라이언트 측 보안은 기기의 신뢰성을 증명하는 수단이 아니라, 노출을 줄이기 위한 하나의 계층으로 간주해야 합니다.
완성도 높은 설계는 보통 다음을 결합합니다:
- 저장 데이터(At-rest) 보호, 데이터베이스, 파일, 캐시, 환경설정, 다운로드한 문서에 적용.
- 전송 데이터(In-transit) 보호, 요청, 동기화, 업데이트 전달, 서비스 간 통신에 적용.
- 플랫폼 키 저장소 사용, 암호화 키가 일반 애플리케이션 파일에 남지 않도록.
- Code 및 런타임 보호, 난독화, 무결성 검사, 안티 디버깅 조치, 적절한 인증서 검증 포함.
- 통제된 업데이트 채널, 서명된 릴리스는 이전 버전에 내재된 보안 가정을 유지해야 하기 때문.
- 문서화된 컴플라이언스 제어, 책임 소재, 증적, 모니터링, 대응 절차 포함.
규제 준수 의무는 부담이 될 수 있지만, 엔지니어링 규율을 강화하는 계기가 되기도 합니다. GDPR, HIPAA, PCI DSS, SOC 2와 같은 규제는 암호화를 단순히 체크리스트 중 하나로 취급하지 않습니다. 팀은 무엇을 보호해야 하는지, 키를 어떻게 제어하는지, 그리고 보안 조치가 의도대로 작동하고 있음을 어떻게 증명할 수 있는지를 명확히 이해해야 합니다.
저장 시 암호화 vs 전송 중 암호화
등기 우편으로 보내는 기밀 문서를 생각해 보세요. 밀봉된 봉투는 전달 과정에서 메시지를 보호합니다. 하지만 수신자가 봉투를 연 후에도, 문서는 잠금 장치가 있는 보관함에 안전하게 보관되어야 합니다. 전송 중 암호화(Encryption in transit)는 데이터의 이동을 보호하며, 저장 시 암호화(Encryption at rest)는 데이터의 저장을 보호합니다. 봉투와 보관함은 서로 다른 문제를 해결합니다.
저장 시 암호화
저장 시 암호화는 데이터가 기기, 서버 디스크, 백업, 데이터베이스 또는 이동식 볼륨에 머물 때 적용됩니다. 모바일 플랫폼에서는 OS 차원의 보호 기능이 기기 일부를 자동으로 암호화할 수 있지만, 애플리케이션은 여전히 안전한 저장 위치, 액세스 제어 및 키 사용 방식을 직접 선택해야 합니다. 민감한 애플리케이션 파일은 암호화된 데이터 바로 옆에 키를 두는 대신, 플랫폼에서 지원하는 암호화 기술을 사용하고 보호된 저장소에 키를 보관해야 합니다.
여기서는 인증된 암호화(Authenticated encryption)가 중요합니다. OWASP는 플랫폼 암호화 API, 사용 가능한 경우 하드웨어 기반 키 저장소, 그리고 다음과 같은 인증 모드 사용을 권장합니다. AES-GCM 또는 AES-CCM, 이는 콘텐츠를 숨길 뿐만 아니라 변조 여부를 감지하는 데에도 도움이 됩니다. 동일한 가이드라인에서는 민감한 데이터를 저장 중(at rest)과 전송 중(in transit) 모두 보호하고, 개인 데이터를 내부 저장소에 보관하며, 독자적인 암호화 알고리즘 대신 플랫폼 구현 방식을 사용할 것을 권장합니다 (OWASP 모바일 애플리케이션 보안 치트 시트).

실제 세부 사항은 플랫폼마다 다릅니다. iOS는 Data Protection 및 Keychain 서비스를 제공합니다. Android는 Keystore 기반 옵션과 암호화된 파일 관리를 돕는 라이브러리를 제공합니다. 데스크톱 애플리케이션은 운영 체제의 자격 증명과 로컬 액세스 제어에 더 크게 의존합니다. Chromium Embedded Framework 환경에서 파일을 다루는 팀은 다음 내용도 검토할 수 있습니다. CEF 문서 저장에 대한 베스트 프랙티스 암호화 알고리즘 자체를 넘어 저장 경계를 확인하기 위해.
전송 중 암호화
전송 중 암호화는 네트워크를 통과하는 요청과 응답을 보호합니다. 적절히 설정된 TLS 연결은 중간자가 애플리케이션 트래픽을 읽거나 수정하는 것을 방지하지만, TLS는 클라이언트가 서버를 올바르게 검증하고 백엔드가 신뢰할 수 있는 인증서를 제시할 때만 작동합니다. 인증서 검사 비활성화, 안전하지 않은 폴백(fallback), 또는 실수로 노출된 평문 엔드포인트는 의도한 보호를 약화시킬 수 있습니다.
인증서 피닝(Certificate pinning)은 팀이 인증서 운영을 직접 제어하고 교체(rotation)를 위한 복구 계획을 갖춘 특정 모바일 시나리오에서 추가적인 검증 계층을 제공할 수 있습니다. 다만, 이는 올바른 TLS를 대체하는 것이 아니며, 잘못된 피닝 설정은 정상적인 사용자의 접속을 차단할 수 있습니다. Capacitor로 앱을 개발하는 팀은 운영상의 트레이드오프가 앱에 적합한지 결정하기 전에 Capacitor 앱을 위한 SSL 피닝을 검토해야 합니다.
두 방식의 실패 모드는 서로 보완적입니다. 전송 보안(Transport security)은 분실된 기기에서 복사된 데이터베이스를 보호하지 못하며, 저장소 암호화(Storage encryption)는 해킹된 연결을 통해 전송된 비밀번호를 보호할 수 없습니다. 두 경로를 모두 설계한 후, 로그, 스크린샷, 임시 파일, 크래시 리포트, 클립보드 내용, 동기화 큐 등 평문(plaintext)이 나타나는 지점을 테스트하세요.
앱 내 Code, 데이터, 시크릿 보호
개발 팀은 종종 “암호화(encryption)”, “난독화(obfuscation)”, “하드닝(hardening)”이라는 용어를 마치 동일한 보안 제어 수단인 것처럼 혼용하곤 합니다. 하지만 이들은 서로 다릅니다. 각 용어는 서로 다른 공격 행위에 대응하며, 이를 혼동하면 잘못된 보안 신뢰를 갖게 됩니다.
난독화 및 코드 경량화(Minification) code를 읽기 어렵게 만듭니다. 이는 애플리케이션 복제나 비즈니스 로직 파악 비용을 높일 수는 있지만, 해당 정보를 반드시 사용해야 하는 애플리케이션이 접근하는 것을 막지는 못합니다. JavaScript 번들에 포함된 API 키, 아카이브 내의 서명 자격 증명, 또는 예측 가능한 함수로 재구성되는 값은 여전히 추출될 수 있습니다. Hermes bytecode와 Electron asar 아카이브는 소스 파일보다 검사하기 번거로울 수 있지만, 패키징이 곧 보안을 의미하지는 않습니다.
데이터 암호화 저장된 사용자 콘텐츠와 로컬 자격 증명을 보호합니다. 플랫폼의 암호화 API를 사용해야 하며, Keychain, Keystore, Secure Enclave, StrongBox 또는 사용 가능한 운영 체제의 유사한 보안 시설에 키를 보관해야 합니다. OWASP의 암호화 테스트 가이드는 소스 code에 비밀번호나 키를 두지 말라고 경고하며, 클라이언트에 남아 있는 비밀 정보는 추출될 수 있음을 강조합니다 ("OWASP MASTG 암호화 테스트).
런타임 보호 변조나 자동화된 악용 가능성을 높이는 조건을 탐지합니다. 탈옥 및 루팅 신호, 디버거 탐지, 애플리케이션 무결성 검사, 어테스테이션(attestation), 인증서 검증 등을 통해 공격을 어렵게 만들거나 대응 신호를 보낼 수 있습니다. 하지만 이 중 어느 것도 기기를 완전히 신뢰할 수 있게 만들지는 않습니다. 의지가 확고한 공격자는 검사 로직을 수정할 수 있으며, 일반 사용자가 휴리스틱 탐지를 유발할 수도 있습니다.
| 보호 계층 | 보호 대상 | 방어할 수 없는 것 |
|---|---|---|
| Code 난독화 | 가독성 및 애플리케이션 로직의 단순 복제 | 앱이 접근 가능한 비밀 정보 추출 |
| 데이터 암호화 | 선택된 저장 데이터의 기밀성 및 무결성 | 정상적인 복호화 후 평문 노출 |
| 런타임 보호 | 변조, 디버깅 및 자동화된 악용 | 런타임을 제어하는 숙련된 공격자 |
더 안전한 설계는 고가치 비밀 정보를 서버에 유지하고, 클라이언트에는 최소 권한의 자격 증명을 부여하며, 오프라인 접근이 필요한 로컬 데이터만 암호화합니다. 토큰 저장 방식은 만료, 취소, 갱신 동작 및 플랫폼 바인딩에 대해 별도로 검토해야 합니다. 모바일 개발자를 위한 안전한 토큰 저장 가이드는 이러한 결정 사항을 구현 요구 사항으로 전환할 때 유용합니다.
단순한 접근 방식은 비밀 정보의 생명주기가 아닌 보안의 외형만 보호하기 때문에 실패합니다. 소스 code에서 값을 XOR 연산하거나, 키를 여러 파일로 분할하거나, JavaScript minification에 의존하는 방식은 실행 중인 애플리케이션이 결국 해당 값을 재구성하여 사용해야 한다는 사실을 바꾸지 못합니다.
iOS, Android, Capacitor, Electron 플랫폼별 고려 사항
동일한 암호화 설계라도 플랫폼마다 제공하는 키 스토어, API, 격리 경계 및 복구 메커니즘이 다르기 때문에 런타임에 따라 다르게 동작합니다. 크로스 플랫폼 추상화 계층이 애플리케이션 code을(를) 단순화할 수는 있지만, 이러한 근본적인 차이까지 없앨 수는 없습니다.
네이티브 모바일 플랫폼
iOS의 경우 Keychain이 보호된 자격 증명 저장소를 제공하며, Secure Enclave)에 키를 저장하세요. 특정 키 작업을 메인 애플리케이션 프로세서로부터 격리할 수 있습니다. 애플리케이션은 여전히 기기 인증 후 데이터를 사용할지, 혹은 사용자 인증 시에만 사용할지 등 사용성 요구 사항에 맞는 액세스 제어를 선택해야 합니다.
Android Keystore는 지원되는 기기에서 하드웨어 기반 경로를 제공하며, StrongBox 사용 가능한 경우 더욱 강력한 격리 환경을 제공할 수 있습니다. Android 개발 팀은 기기 성능, 백업 동작, 인증 요구 사항 및 attestation 신호도 고려해야 합니다. 하드웨어 지원은 균일하지 않으므로, 모든 기기가 동일한 보호 기능을 제공한다고 가정하기보다 명확한 폴백(fallback) 정책을 세워야 합니다.
크로스 플랫폼 셸
Capacitor 애플리케이션은 브릿지를 통해 웹 code과 네이티브 플랫폼 기능을 결합합니다. 이 브릿지는 단순한 편의 계층이 아니라 보안 경계입니다. localStorageLocalStorage, IndexedDB, 일반적인 웹 설정(preferences)은 기본적으로 암호화된 비밀 저장소로 취급해서는 안 됩니다. 팀은 네이티브 스토리지 플러그인을 명시적으로 선택하거나, 플랫폼의 보호된 키 기능을 사용하는 네이티브 모듈을 직접 구현해야 합니다.
Electron은 위협 모델이 다릅니다. 렌더러 프로세스는 웹 콘텐츠를 처리하는 반면, 메인 프로세스는 더 넓은 권한을 가집니다. 따라서 민감한 작업은 노출된 렌더러에서 수행하지 않아야 합니다. Electron의 safeStorage 운영 체제의 자격 증명 보호 기능을 사용할 수 있지만, 보안 수준은 호스트 OS, 사용자 계정, 데스크톱 설정 및 프로세스 격리 상태에 따라 달라집니다. 모바일 플랫폼이 보호된 키를 격리하는 방식처럼 하드웨어 수준의 자동 격리가 보장되지는 않습니다.
| 플랫폼 | 키 저장 | 암호화 API | 기본 위협 모델 |
|---|---|---|---|
| iOS | Keychain 및 지원되는 경우 Secure Enclave | Apple 플랫폼 암호화 및 Data Protection | 기기와 앱은 분리되어 있으나, 기기나 런타임이 탈취될 경우 사용 내역이 노출될 수 있음 |
| Android | Keystore 및 지원되는 경우 StrongBox | Android 플랫폼 암호화 및 Jetpack 보안 컴포넌트 | 하드웨어 및 소프트웨어 기능은 기기마다 다릅니다 |
| Capacitor | 플러그인 또는 커스텀 브릿지를 통한 code 네이티브 스토리지 선택 | Web API 및 네이티브 플랫폼 API | Web 에셋은 네이티브 셸 내부에서 실행되므로 보안 스토리지 권한을 자동으로 상속받지 않습니다 |
| Electron | 다음과 같은 API를 통한 OS 자격 증명 기능 safeStorage |
Node 및 Chromium 호환 애플리케이션 API | Renderer 노출 및 호스트 레벨 액세스가 핵심 고려 사항입니다 |
팀은 제품을 단순히 “모든 플랫폼에서 암호화됨”이라고 설명하기보다 타겟별 동작을 문서화해야 합니다. 플랫폼 차이에 대한 Capacitor 접근 방식 플랫폼별 결정 사항이 투명하게 유지되어야 하는 지점으로 브릿지를 정의하는 데 도움을 줍니다.
키 관리와 클라이언트 측 보안의 한계
암호화는 키 관리가 키를 안전하게 보호할 때만 유효합니다. 유용한 라이프사이클은 다음 5단계로 구성됩니다: 생성, 배포, 저장, 순환(rotation), 그리고 폐기. 각 단계마다 서로 다른 장애 모드가 발생할 수 있습니다.
신뢰할 수 있는 플랫폼 또는 서버의 암호화 API를 사용하여 키를 생성하세요. 번들에 키를 직접 포함하는 대신 인증된 프로토콜을 통해 배포하세요. 가능한 경우 보호된 플랫폼 시설에 저장하세요. 정책, 리스크 또는 암호화 요구 사항에 따라 키를 순환(rotate)하세요. 기기, 계정 또는 세션의 데이터 복호화 권한을 중단해야 할 경우 서버 제어 권한을 통해 액세스를 폐기하세요.
사용자가 기기를 제어하고 애플리케이션 상태를 조사할 수 있으므로, 이러한 작업에서 클라이언트는 인프라보다 보안에 취약합니다. 사용자 유도 패스프레이즈로 보호되는 오프라인 데이터의 경우, 복구 및 사용성 측면의 결과를 감수한다면 클라이언트 보유 키가 의미가 있을 수 있습니다. 하지만 광범위한 백엔드 액세스 권한을 가진 API 토큰의 경우에는 훨씬 더 위험합니다. 공격자가 해당 토큰을 탈취하면 로컬 데이터베이스에 적용된 암호화는 토큰의 원격 권한을 제한할 수 없습니다.
Envelope encryption은 데이터 암호화 키와 마스터 키를 분리합니다. 애플리케이션은 수명이 짧은 데이터 키로 로컬 객체를 암호화하고, 서버 측 키 관리 서비스나 HSM 기반 시스템이 래핑 키를 보호합니다. 원격 키 릴리스 설계에서는 복호화에 필요한 키를 제공하기 전, 인증된 기기, 사용자, 정책 결정 또는 증명(attestation) 신호를 요구할 수 있습니다. 이러한 패턴이 탈취된 클라이언트를 완벽히 보호하지는 못하지만, 기기에 영구적으로 머무는 권한의 범위를 줄여줍니다.

OWASP는 로컬 민감 데이터를 개인 식별 정보, 암호화 자료, 비밀 정보 및 API 키를 포함하는 것으로 정의합니다. 또한 암호화를 안전한 로컬 스토리지, 키 로테이션, 사용 후 제로화(zeroization)와 같은 라이프사이클 제어와 연결합니다. 아키텍처 원칙은 간단합니다:
가치가 높은 비밀 정보는 팀이 제어하는 시스템에 보관하세요. 클라이언트에는 현재 작업에 필요한 최소한의 권한만 부여해야 합니다.
릴리스 시스템의 경우, 키 관리는 업데이트 서명 및 전달에도 적용됩니다. 팀은 누가 번들을 서명할 수 있는지, 서명 자격 증명이 어디에 저장되는지, 액세스 감사 방법은 무엇인지, 그리고 서명 자격 증명이 유출되었을 때 어떻게 교체할지를 정의해야 합니다. 다음 가이드는 키 관리를 통한 OTA 업데이트 보안 방법을 통해 애플리케이션 암호화와 업데이트 라이프사이클을 연결하는 데 도움을 줍니다.
규제 및 컴플라이언스 영향
컴플라이언스 팀은 단순히 “앱에 암호화를 적용했습니다”라는 말만으로는 충분한 증거로 인정하지 않습니다. 대신 어떤 데이터가 보호되는지, 어떤 알고리즘과 프로토콜이 활성화되어 있는지, 키 관리는 누가 하는지, 접근 제어는 어떻게 이루어지는지, 그리고 설정 드리프트(configuration drift)를 어떻게 감지하는지 구체적으로 요구합니다.
EU의 GDPR 본문에 반영된 것처럼, GDPR 제32조는 암호화를 리스크를 줄이기 위한 적절한 기술적 조치로 다룹니다. 이 의무는 리스크 기반이므로, 조직은 보안 조치를 개인 데이터의 성격 및 처리 환경과 연결하여 설명할 수 있어야 합니다. 의료 정보, 신원 데이터 또는 금융 기록을 다루는 모바일 앱은 로컬 저장, 전송, 접근 및 사고 대응에 대해 방어 가능한 논리를 갖추어야 합니다.
HIPAA 보안 규칙은 전자 보호 건강 정보(ePHI)에 대한 암호화를 무조건적인 기술적 체크리스트가 아닌 'addressable safeguard(선택적 보호 조치)'로 취급합니다. 즉, 대상 기관이나 비즈니스 파트너는 암호화가 합리적이고 적절한지 평가하고, 그 결정을 문서화해야 하며, 암호화를 구현하지 않을 경우 대안적인 조치를 적용해야 합니다. 구체적인 가이드는 HHS 보안 규칙을 따릅니다.
PCI DSS는 저장된 카드 소유자 데이터와 개방형 네트워크를 통한 전송 데이터를 구분합니다. 팀은 암호화 결정 사항을 관련 요구 사항에 매핑해야 하며, 결제 데이터를 불필요하게 저장하지 않도록 주의해야 합니다. 최신 문구와 범위를 확인하려면 PCI 보안 표준 협회(PCI Security Standards Council)의 문서 라이브러리를 참조하는 것이 가장 정확합니다.
SOC 2 심사원은 통제 항목이 실제로 작동한다는 증거에 집중합니다. 여기에는 키 관리 정책, TLS 설정, 암호화 알고리즘 목록, 액세스 로그, 변경 승인 내역, 침해 사고 기록, 테스트 결과, 그리고 서명된 릴리스가 정해진 프로세스를 따랐다는 증거 등이 포함될 수 있습니다. 모니터링되지 않는 문서화된 통제 항목은 효과적인 운영을 입증하기 어렵습니다.

이들의 공통점은 입증 가능성입니다. 감사 전 주에 급하게 준비하지 말고, 앱 암호화를 구현하는 과정에서 증거 추적 경로를 함께 구축하세요.
흔한 실수와 보안 강화 베스트 프랙티스
대부분의 암호화 실패는 평범한 엔지니어링 결정에서 시작됩니다. 개발자가 시작 시점에 사용 가능한 token이 필요하거나, 팀에서 오프라인 검색 속도를 높이고 싶어 하거나, 릴리스 프로세스에서 hotfix를 빠르게 배포해야 하는 경우입니다. 이러한 지름길이 신뢰 모델의 영구적인 일부가 될 때 위험이 발생합니다.
최근 모바일 리스크 연구 보고에 따르면 평가 대상 앱의 60% 이상이 민감한 데이터에 보안이 취약하거나 오래된 암호화 방식을 사용하고 있으며, 반면 약 3분의 1은 초기화 벡터(IV)를 재사용하고 있습니다 및 20%는 하드코딩된 정적 값 사용. 이러한 결과는 질문을 “앱이 암호화하는가?”에서 “실제 사용 환경에서 구현이 기밀성과 무결성을 유지할 수 있는가?”로 바꿉니다. (SC World의 모바일 앱 리스크 보고서)
| 흔한 실수 | 보안 강화 실무 |
|---|---|
| 소스 코드, 바이트코드 또는 번들에 API 키나 암호화 키를 하드코딩함 | 중요한 자격 증명은 서버 측에 보관하고, 기기 범위의 데이터는 플랫폼 보호 저장소를 사용하세요 |
| SQLite 데이터베이스는 암호화하면서 평문 캐시, 내보내기 파일, 로그 또는 백업은 그대로 두는 경우 | 민감한 데이터의 모든 복사본을 파악하고 임시 파일에도 동일한 저장 정책을 적용하세요 |
| 일반 웹 스토리지에 리프레시 토큰을 저장함 | 플랫폼 기반 자격 증명 저장소를 사용하고, 토큰 범위를 제한하며, 서버 측 무효화 기능을 지원하세요 |
| 직접 암호화 알고리즘을 구현하거나 키 난독화 방식을 임의로 만드는 경우 | 검증된 플랫폼 API와 인증된 암호화 모드 사용 |
| 연결 문제를 해결하려고 인증서 검증을 비활성화하는 경우 | TLS를 올바르게 구성한 뒤, 검증된 복구 프로세스와 함께 피닝 검토 |
| minification을 비밀 정보 보호 수단으로 간주하는 경우 | 클라이언트 code에서 비밀 정보를 제거하고, 난독화는 역공학 비용을 높이는 용도로만 사용 |
| 앱 무결성 검사와 attestation 신호 누락 | 필요한 경우 릴리스 ID를 검증하고, 신호로 액세스를 조정하거나 검토를 트리거 |
| 서명되지 않았거나 제어가 취약한 업데이트 허용 | 릴리스 아티팩트에 서명하고, 서명 자격 증명을 보호하며, 업데이트 결과를 모니터링 |
별도의 위협 보고서에 따르면 스파이웨어 조직이 앱을 사칭하고 기기 자체를 악용해 Signal과 WhatsApp 계정을 공격하고 있습니다. 같은 보고서는 모바일 위협 평가를 인용했는데, 2025년 상반기 Android 스마트폰 공격은 2024년 상반기 대비 29% 증가했습니다 (CISA 관련 보고서에 대한 The Register의 보도). 교훈은 암호화가 실패했다는 게 아닙니다. 공격자는 보호된 암호문을 우회할 수 있는 기기, 계정, 세션, 업데이트 경로를 자주 선택합니다.
각 보안 강화 관행을 자동화된 릴리스 규칙으로 만드세요. CI에서 알려진 secret 패턴을 거부하고, 커스텀 암호화 code를 플래그하고, 서명 단계를 검증하고, bundle 내용을 검사하며, 저장 또는 전송 설정이 바뀌면 보안 리뷰를 요구할 수 있습니다. 목표는 잘못된 결정이 배포되는 dependency가 되기 전에 잡아내는 것입니다.
암호화 계획에 모두 통합하기
암호화 계획은 엔지니어링 계약서처럼 읽혀야 합니다. 앱이 무엇을 보호하는지, 키가 어디에 있는지, 어떤 컴포넌트가 plaintext를 볼 수 있는지, 팀이 매 릴리스 후에도 제어가 계속 활성 상태임을 어떻게 증명하는지를 명시해야 합니다.
다음으로 시작하세요 데이터 분류. 민감도와 보존 요구사항에 따라 레코드, token, 문서, logs, 캐시, 백업, analytics 필드를 분류하세요. 알고리즘을 선택하기 전에 로컬 복사본을 최소화하세요. 기기에 도달하지 않는 데이터에는 기기 저장소 설계가 필요 없습니다.
그다음, 저장 및 전송 결정을 문서화하세요:
- At-rest 방식: 인증 암호화(authenticated encryption), 플랫폼 관리형 키 저장소, 보호된 파일 위치, 백업 동작, 삭제 또는 zeroization 처리 방식을 선택하세요.
- In-transit 프로토콜: TLS 설정, 인증서 검증, 엔드포인트 정책, 위협 모델에 pinning이 적절한지를 정의하세요.
- 키 관리(Key custody): 레코드 생성, 액세스, 배포, 순환(rotation), 폐기, 복구 및 긴급 교체 절차.
- Code 및 런타임 제어: 난독화, 무결성 검사, 증명(attestation), 디버거 탐지 및 민감한 화면 보호 기능의 적용 범위를 결정합니다.
- 감사 증거: 구성 인벤토리, 액세스 로그, 릴리스 승인, 테스트 결과, 사고 기록 및 예외 사항을 기록합니다.
순서가 중요합니다. 데이터 분류에 따라 보호 대상을 결정하며, 이 결정이 저장 방식과 키 관리 방식을 결정합니다. 그다음 전송 및 업데이트 제어를 통해 신뢰할 수 있는 서비스와 클라이언트 사이의 경로를 보호합니다. Capacitor 및 Electron 팀은 타겟별로 검토를 반복해야 합니다. iOS 네이티브 키 스토어, Android 하드웨어 기반 옵션, 브라우저 스토리지 API, 데스크톱 자격 증명 방식은 제공하는 보안 보증이 서로 다르기 때문입니다.

업데이트 채널은 계획의 사후 단계가 아니라 계획의 일부로 포함되어야 합니다. 서명된 릴리스는 code의 무결성을 유지할 수 있으며, 제어된 타겟팅, 롤백 방지, 릴리스 관측성(observability)은 취약한 빌드나 설정이 사용자에게 전달되었을 때 팀이 신속히 대응할 수 있도록 돕습니다. 앱에 오프라인 데이터가 추가되거나, 스토리지 플러그인을 변경하거나, 새로운 백엔드 권한을 도입하거나, 업데이트 서명 및 전달 방식이 변경될 때마다 계획을 재검토하십시오.
Capgo는 CapacitorJS 및 Electron 애플리케이션을 위한 서명된 Live Update를 제공합니다. JavaScript code 및 에셋에 대한 번들 암호화 지원, 제어 가능한 릴리스 채널, 롤백 방지, 기기별 업데이트 관측성을 갖추고 있습니다. 자세한 내용은 Capgo 제어된 업데이트 경로가 앱 암호화 및 릴리스 거버넌스 계획을 어떻게 지원할 수 있는지 확인해 보세요.