AI의 도움으로 아래와 같은 정보를 확인했다.
나는 아래 방법 중에 안드로이드용 so 파일을 제작해서 사용하는 방법을 이용하려고 한다.
기존에 C#으로 개발한 프로그램도 인증이나 Key 처리는 DLL을 제작해서 사용을 했기 때문이다.
NET MAUI(Multi-platform App UI)로 개발된 안드로이드 앱(APK/AAB)도 C# 윈도우 프로그램과 마찬가지로 디컴파일이 가능하며, 소스 코드를 복원하는 것이 비교적 쉽습니다.
특히 전력 제어 장치(Recloser 등)와 같은 중요 인프라를 다루는 소프트웨어에서 **하드코딩된 암호화 키(Key)**가 노출되는 것은 보안상 매우 치명적입니다. 제공해주신 문서 내용과 귀하의 개발 환경(C++, C#, MAUI)을 고려하여, 디컴파일 위험성과 암호화 키 보호 방안을 정리해 드립니다.
1. MAUI APK 디컴파일 가능 여부
결론: 가능합니다.
- 원리: MAUI로 빌드된 APK 파일은 내부적으로 압축 파일과 같습니다. 이 압축을 풀면 assemblies 폴더 내에 .dll 파일들이 들어 있습니다. 이 DLL들은 C# 코드가 컴파일된 MSIL(Intermediate Language) 형태이므로, dotPeek, ILSpy, dnSpy 같은 도구를 사용하면 원본 소스와 거의 유사한 수준으로 복원이 가능합니다.
- 위험성: 소스 코드 내에 string SecretKey = "1234...";와 같이 키를 문자열로 선언해 두었다면, 디컴파일 툴의 '문자열 검색' 기능만으로도 몇 초 안에 키를 찾아낼 수 있습니다.
2. 암호화 키 보호 및 소스 코드 보안 전략
완벽한 방어는 불가능하지만, 해커가 키를 찾아내는 데 드는 비용과 시간을 비약적으로 높이는 '심층 방어(Defense in Depth)' 전략을 사용해야 합니다.
A. 코드 난독화 (Obfuscation) [필수]
가장 기본적이고 필수적인 조치입니다. 난독화 도구는 클래스, 메서드, 변수 이름을 a(), b() 처럼 의미 없는 문자로 바꾸고, 제어 흐름을 꼬아서 코드를 읽기 어렵게 만듭니다.
- 도구:
- Dotfuscator: Visual Studio에 기본 포함(Community 버전)되어 있거나 상용 버전을 사용할 수 있습니다.
- ConfuserEx: 오픈 소스 난독화 도구로 강력한 기능을 제공합니다.
- 효과: 키 변수명이 숨겨지고 코드가 꼬이지만, 문자열(String) 자체가 평문으로 남아있으면 여전히 위험합니다. 따라서 '문자열 암호화(String Encryption)' 옵션을 반드시 켜야 합니다.
B. NDK(Native Development Kit) 활용 (C++ 라이브러리) [추천]
귀하께서 C++ 개발 경험이 있으시므로 이 방법이 매우 효과적입니다.
- 방법: 중요한 암호화 키 생성 로직이나 통신 프로토콜의 핵심 부분을 **C++(.so 라이브러리)**로 작성하고, MAUI(C#)에서 JNI(Java Native Interface) 또는 P/Invoke를 통해 호출합니다.
- 장점: C++로 컴파일된 .so 파일은 기계어(Assembly)로 되어 있어, C# DLL(IL 코드)보다 리버스 엔지니어링 난이도가 훨씬 높습니다. (IDA Pro 같은 전문 툴을 써야 분석 가능)
- 적용 예시:
- 제공된 자료에서 언급된 AES-CMAC 및 AES-CTR 로직과 키 관리 부분을 C++ 라이브러리로 구현하여 APK에 포함시킵니다.
C. Android Keystore 시스템 사용 (Secure Storage) [가장 안전]
키를 소스 코드에 두지 않고, OS가 제공하는 보안 영역에 저장하는 방식입니다.
- 방법: MAUI의 Microsoft.Maui.Storage.SecureStorage 또는 안드로이드 네이티브 API인 Android Keystore System을 사용합니다.
- 원리: 앱이 설치된 후, 암호화 키를 TEE(Trusted Execution Environment) 또는 **SE(Secure Element)**라는 하드웨어 보안 영역에 저장합니다. 이 영역은 루팅된 폰에서도 추출이 매우 어렵습니다.
- 시나리오:
- 앱 최초 실행 시 서버로부터 키를 받거나, 난수를 통해 생성합니다.
- 생성된 키를 SecureStorage에 저장합니다.
- 이후 통신 시 저장소에서 키를 꺼내 사용합니다.
D. 키 파생 및 동적 생성 (Key Derivation)
소스 코드에 '완성된 키'를 두지 않고, 런타임에 계산해서 만듭니다.
- 방법: 키를 여러 조각으로 나누어 코드 곳곳에 숨기거나, 특정 알고리즘(XOR 연산 등)을 통해 런타임에 조립하여 메모리 상에서만 잠시 존재하게 합니다.
- 참고: 제공된 자료의 IEEE 1686 보안 표준 을 준수하기 위해, 고정된 마스터 키보다는 Diffie-Hellman (ECDH) 알고리즘을 사용하여 통신 세션마다 새로운 세션 키를 생성하는 방식이 가장 안전합니다. 블루투스 연결 시 이 과정을 수행하면 고정 키 탈취 위험을 원천 차단할 수 있습니다.
3. 요약 및 제안
귀하의 프로젝트(CMR 안드로이드 앱) 에 적합한 단계별 보안 조치는 다음과 같습니다.
- 난독화 적용 (기본): 배포 전 반드시 Dotfuscator 등을 통해 난독화를 수행하십시오.
- C++ 네이티브 이전 (중급): 이미 C++에 익숙하시므로, AES-CMAC, AES-CTR 관련 키 처리 로직을 C++(.so)로 옮기십시오. 이것만으로도 일반적인 디컴파일 시도는 대부분 막을 수 있습니다.
- Android Keystore 활용 (고급): 키를 소스 코드에 하드코딩하지 말고, 앱 실행 시 안전한 저장소(Keystore)에서 불러오도록 설계하십시오.
'.NET > MAUI' 카테고리의 다른 글
| .NET MAUI Android 프로젝트에 .so 파일 포함 설정 가이드 (0) | 2026.01.14 |
|---|---|
| MSVS 2022에서 SO 파일 제작 방법 (0) | 2026.01.12 |
| MAUI 함수 호출 지연 방법 비교 (0) | 2025.12.11 |
| MSVS에 빌드 옵션에 Android 로컬 디바이스가 표시되지 않을 때 (0) | 2025.12.08 |
| MAUI 상대/절대 경로 설명 (0) | 2025.11.24 |