Android 앱 서명: 작동 방식 및 중요한 이유
Android 휴대폰에 앱을 설치할 때마다 백그라운드에서 조용하지만 중요한 보안 검사가 수행됩니다. 휴대전화에서 APK 패키지의 디지털 서명를 확인합니다. 이 암호화 핸드셰이크는 악의적인 해커가 앱을 맬웨어로 "중독"시키는 것을 방지하는 동시에 개발자가 신원을 잃지 않고 업데이트를 푸시할 수 있도록 보장합니다.
앱을 작성하는 경우 서명은 올바르게 수행해야 하는 작업입니다. Android를 만져보고 싶다면 시스템에서 이해해야 할 가장 만족스러운 부분 중 하나입니다. 어느 쪽이든 앱 서명 작동 방식는 시간을 투자할 가치가 있습니다. 아래에서는 기술, 서명 체계가 어떻게 발전했는지, 온라인으로 수동으로 인증서 확인를 수행하는 방법을 살펴보겠습니다.
- 모든 Android 앱에 서명이 필요한 이유와 관련 암호화(RSA/EC).
- v1(JAR), v2, v3, v4 서명 구성표의 차이점과 현재 앱에서 사용해야 하는 구성표입니다.
- Android가 서명 연속성을 기반으로 업데이트 허용 여부를 결정하는 방법입니다.
- 키 순환을 통해 개발자가 기존 설치를 중단하지 않고 서명 키를 변경할 수 있는 방법.
- 명령줄이나 브라우저 기반 검증자를 사용하여 APK 서명을 직접 확인하는 방법
앱 서명이란 무엇입니까?
기본적으로 앱 서명은 개발자가 개인 키를 사용하여 앱 파일에 대한 서명 블록을 생성하는 프로세스입니다. 그런 다음 해당 공개 키가 META-INF 폴더 내의 APK에 포함됩니다. 휴대폰에서 앱을 설치하려고 하면 공개 키를 사용하여 서명이 파일 내용과 일치하는지 확인합니다.
이는 두 가지 주요 속성을 제공합니다.
- 불변성: 앱 코드의 단일 바이트가 변경되면(예: 트로이 목마에 의해) 서명이 더 이상 파일과 일치하지 않으며 Android는 해당 파일의 설치를 거부합니다.
- 신원 증명: 앱이 기존 앱을 업데이트하려고 하면 해당 서명이 일치해야 합니다. 이것이 공식 앱 위에 변조된 Facebook 앱을 설치할 수 없는 이유입니다.
서명 방식의 진화
Google은 속도와 보안을 모두 개선하기 위해 서명 메커니즘을 지속적으로 업그레이드해 왔습니다.
- V1(Jar 서명): APK(ZIP) 내의 개별 파일에 서명합니다. OS가 모든 파일의 압축을 풀고 확인해야 하기 때문에 속도가 느립니다. 또한 특정 ZIP 조작에도 취약합니다.
- V2(APK 서명 체계): APK의 전체 바이너리 블록에 서명합니다. 확인을 위해 압축을 풀 필요가 없으므로 놀라울 정도로 빠릅니다. Android 7.0(누가)부터 도입됐다.
- V3(키 순환): 키의 "계보"를 추가하여 V2를 확장합니다. 이를 통해 개발자는 새 키가 이전 키의 승인된 후속 키임을 증명할 수 있습니다. Android 9.0(Pie)에서 도입되었습니다.
- V4(스트리밍 서명): 증분 설치용으로 특별히 설계되어 USB 또는 Wi-Fi를 통해 다운로드되는 동안 앱을 확인할 수 있습니다.
사이드로딩에 인증서가 중요한 이유
비공식 소스에서 APK를 다운로드하면 인증서 해싱가 가장 친한 친구가 됩니다. 인증서 지문(예: SHA-256 해시)은 개발자의 서명 키를 고유하게 식별합니다. 각 앱은 모든 업데이트에서 동일한 서명 키를 유지하므로 APK의 지문을 개발자가 게시한 값과 비교하여 정품인지 확인할 수 있습니다.
APK가 가짜라고 의심되면 온라인 APK 검증기를 통해 실행해야 합니다. 우리 도구는 다음을 보여줍니다:
- 서명자의 일반 이름(CN)입니다(예: "Android").
- 인증서의 유효기간입니다.
- SHA-1/SHA-256 지문.
Android가 설치 시 서명을 확인하는 방법
"인증서 확인" 단계는 너무 자주 생략되어 APK를 탭하고 Android가 설치 여부를 결정할 때 OS가 실제로 수행하는 작업을 살펴보는 것이 좋습니다.
- APK를 ZIP으로 열고 서명 블록을 찾으세요. 중앙 디렉터리 바로 앞에 구조화된 블록인 v2/v3 서명의 경우; 레거시 v1 체계의 경우 META-INF/*.RSA, *.DSA 또는 *.EC의 콘텐츠입니다.
- APK의 다른 모든 바이트에 대해 SHA-256 다이제스트를 계산합니다. 서명 블록은 자체 다이제스트에서 제외됩니다. 다른 모든 것은 정의된 청크로 해시됩니다.
- 서명 블록에 기록된 다이제스트와 비교하여 각 청크의 다이제스트를 확인합니다. 개발자가 파일에 서명한 이후 단일 바이트라도 변경된 경우 다이제스트가 일치하지 않으며 일반 "앱이 설치되지 않음" 오류와 함께 설치가 거부됩니다.
- 서명 블록 자체가 인증서의 개인 키로 생성되었는지 확인하십시오. 인증서의 공개 키는 블록의 암호화 서명을 확인하는 데 사용됩니다. 성공적인 확인은 파일에 서명한 사람이 이 인증서와 쌍을 이루는 개인 키를 소유했음을 의미합니다.
- 인증서 지문을 동일한 패키지 이름의 기존 설치와 비교합니다. 패키지가 이미 설치되어 있고 새 APK가 다른 인증서로 서명된 경우 INSTALL_FAILED_UPDATE_INCOMPATIBLE로 설치가 거부됩니다. 이것이 OS의 주요 사칭 방지 방어책입니다. 악의적인 행위자가 은행의 서명 키를 훔치지 않는 한 은행 앱을 자신의 복사본으로 대체할 수 없습니다.
이 중 어느 것도 개발자가 신뢰할 수 있다는 것을 증명하지 못합니다. 단지 설치하려는 파일이 서명한 파일과 바이트가 동일하고 다른 사람이 이를 변조하지 않았다는 사실만 입증됩니다. 개발자에 대한 신뢰는 별도의 결정이며, 설치할 소스를 결정하여 결정합니다.
"서명 불일치"가 실제로 의미하는 것
사이드로딩을 할 때 사람들이 겪는 가장 일반적인 놀라움은 업데이트 시 발생하는 "서명 불일치" 오류입니다. 실제로 일어나는 일은 다음과 같습니다.
- Play 스토어에서 앱 X 버전 1.0를 설치했습니다.
- Play가 아닌 소스에서 앱 X 버전 1.1를 다운로드합니다.
- OS에는 동일한 패키지 이름(com.example.app이 표시되지만 APK는 다른 인증서(원래 게시자의 서명 키가 아닌 사이드 소스의 서명 키)로 서명됩니다). 설치를 거부합니다.
실제로는 두 가지 방법으로 이런 일이 발생합니다.
- 타사 APK는 진짜 다른 출판사에서 나온 거야입니다(예: '수정된' 또는 '패치된' 복사본). 설치를 거부하는 것이 올바른 행동입니다. 이를 설치한다는 것은 은행 앱이 이미 접촉한 것과 동일한 데이터를 가진 낯선 사람을 신뢰한다는 것을 의미합니다.
- 타사 APK는 공식 APK 재업로드이지만 Google의 Play 앱 서명 시스템은 사용자의 업로드 키 래퍼를 사용하여 각 사용자의 다운로드에 서명합니다. 두 장치에서 동일한 개념적 앱 버전에 대해 약간 다른 서명 데이터를 볼 수 있는 경우가 있습니다. 이 경우 루트의 인증서 지문은 여전히 일치합니다. APK 검증자로 확인할 수 있습니다.
인증서 지문 진심으로가 기존 설치와 다른 경우 유일한 방법은 대체 항목을 사이드로드하기 전에 먼저 현재 복사본을 제거(데이터 손실)하는 것이며 서명 확인을 비활성화하지 않는 것입니다.
나만의 서명 키 생성하기(개발자용)
Android 앱을 빌드하는 경우 결국 자체 빌드에 서명해야 합니다. Java SDK에서 keytool를 사용하는 표준 한 줄 명령은 다음과 같습니다.
keytool -genkeypair -v \
-keystore my-release.keystore \
-alias my-app -keyalg RSA -keysize 2048 \
-validity 10000
알아야 할 두 가지 사항:
- 효력 중요: OS는 거의 만료되었거나 만료된 키로 서명된 업데이트를 손상된 것으로 처리하므로 10000일(약 27년)이 일반적인 값입니다. 수명이 긴 키를 한 번 생성하고 보호하세요.
- 일단 게시되면 키를 쉽게 전환할 수 없습니다. v3 서명 방식은 회전 키를 명시적 기능으로 추가합니다. 즉, 기존 인증서는 저장된 증명을 통해 새 인증서를 "축복"하여 OS가 ID 연속성을 유지하면서 새 키의 업데이트를 수락할 수 있도록 합니다. v3가 없으면 원래 키를 잃어버리면 기존의 모든 설치가 분리됩니다.
사이드로드된 테스트 빌드의 경우 서명되지 않은 디버그 키 저장소가 괜찮습니다. 프로덕션의 경우 오프라인 백업에 저장된 비밀번호로 보호된 장기 유효 키 저장소를 사용하세요.
일반적인 서명 문제
- 자체 서명된 인증서: 대부분의 Android 앱은 자체 서명되어 있습니다. 웹사이트용 SSL과 달리 Android 앱 서명에는 중앙 권한이 없습니다. 개발자를 직접 신뢰해야 합니다.
- 테스트용으로 제작된 디버그 인증서: 앱은 일반 "디버그" 키를 사용합니다. 이러한 앱은 대중에게 공개되어서는 안 되며 많은 보안 필터에 의해 차단됩니다.
- 키 손실: 개발자가 개인 키 저장소를 분실한 경우 절대 앱을 다시 업데이트할 수 있습니다. 그들은 다른 패키지 이름을 가진 "새" 앱을 출시해야 합니다.
대상 SDK에 적합한 서명 방식 선택
앱 서명은 Android의 많은 보안을 조용히 뒷받침합니다. 개인/공개 키 관계가 클릭되면 사이드로드된 앱의 장점을 판단하고 개발자가 서명한 이후 설치 중인 앱이 변경되지 않았는지 확인할 수 있습니다. Android 내부에 대한 자세한 내용은 XAPK 형식 가이드를 참조하세요.