DEV Community

Cover image for Android의 App Signing Flow
Chan
Chan

Posted on

Android의 App Signing Flow

범용적인 Digital Signature와 Signing의 의미

  • 서명이란 이름에서 알 수 있듯이, 디지털 세계에서 사인을 남기는 행위를 실현한 것이 디지털 서명이다.
  • 디지털 서명은 전송된 데이터가 변조되지 않았다는 보증수표의 역할을 한다.
  • App Signing은 애플리케이션 파일에 대해 디지털 서명을 생성하는 과정을 의미한다.

안드로이드 생태계에서의 Signing

안드로이드에서는 개발자가 앱의 소유주이고, 배포된 파일이 임의로 조작되지 않았다는 증거를 남기기 위해 위한 디지털 서명을 한다. 이를 증명해야 하는 이유는 전송 과정에서 파일이 임의로 조작될 수 있기 때문이다. 중간자에 의해 악성코드가 심어진 파일을 사용자가 다운로드하게 된다면 심각한 개인정보 유출로 이어질 수 있기에 디지털 서명이 필요하다.

signing and digital signature

앱의 파일이 조작될 수 있는 경로는 다음과 같다.

  • 개발자가 애플리케이션을 업로드할 때
  • 사용자가 플레이스토어에서 앱을 다운로드할 때

코드가 조작될 수 있는 경로도 위와 같으므로, 디지털 서명 검증도 해당 과정에서 이루어진다.

Signing process

signing process

개발자는 앱의 소유주임을 증명할 수단으로 keystore를 가지고 있다. keystore는 private key와 public key가 들어있는 certificate을 가지고 있는 파일이다.

  1. 각각의 파일을 해시 함수를 사용하여 해시값으로 변환한다.
  2. 변환된 해시값을 key store의 private key를 이용하여 암호화한다. 암호화된 결과물을 digital signature라고 부른다.
  3. apk 완성한다. apk는 다음과 같이 구성된다.
    • .SF: 각각의 파일을 해시로 변환한 것
    • RSA: 디지털 서명
    • .X509: 공개키 인증서

Digital Signature Verification

앱 설치 및 업데이트 시, 패키지에 포함된 Digital Signature를 통해 이 APK가 이전 버전과 같은 키로 서명되었는지 검증한다.

Signing과 Digital Signature를 다이어그램으로 단계별로 나타내면 다음과 같다.

%%{init: {'theme': 'base', 'themeVariables': {
    'fontSize': '16px',
    'nodeSpacing': '40',
    'edgeLabelFontSize': '12px'
}}}%%
flowchart TB
  subgraph SP["**Signing Process**"]
    direction TB
    SP1["**Keystore**: private key, public key certificate (X509)"]
    SP2["**Hash each file**: SHA256 classes.dex resources AndroidManifest → SF"]
    SP3["**Create Digital Signature**: encrypt SF with private key → RSA/DSA"]
    SP4["**Package APK**: include DEX, META-INF (SF, RSA, X509)"]
    SP1 --> SP2 --> SP3 --> SP4
  end

  %% 시그니처→검증 프로세스 연결
  SP4 --> VP1

  subgraph VP["**Verification Process**"]
    direction TB
    VP1["**Extract public key** & signature from X509, RSA"]
    VP2["**Recompute hashes** of APK files"]
    VP3["**Decrypt signature** with public key to recover original hashes"]
    VP4["**Compare hashes**: match→allow install/update; mismatch→block"]
    VP1 --> VP2 --> VP3 --> VP4
  end

  %% Certificate consistency check 추가
  VP4 --> CC["**Certificate Consistency Check**: existing app certificate matches new certificate"]
  CC --> Success["**Success**: install/update allowed"]
  CC --> Failure["**Failure**: INSTALL_FAILED_UPDATE_INCOMPATIBLE signature inconsistent"]
Enter fullscreen mode Exit fullscreen mode

Basic signing process

Basic verificiation process

Compare hashes

이 과정을 수행하는 목적은 다음과 같다.

  • 출처 검증: 새로 다운로드 받는 코드가 동일한 개발자(keystore 소유자)가 만든 것인지 확인
  • 무결정 검증: 앱 다운로드 또는 전송 중 코드가 변조 되는지 확인

올바른 private key를 가지고 암호화를 해야, public key로 복호화를 했을 때 원래 가지고 있던 해쉬값을 얻어올 수 있다. 따라서 public key가 올바른 것이고, public key로 복호화를 했을 때 decripted_hash = computed_hash이면 해당 데이터가 본 주인으로부터 온 것임을 보일 수 있다.

Old School (App Signing By Developers)

최종 사용자의 기기에서 앱을 검증할 때 개발자의 private key로 signing한 app에 대하여 검증하는 방식이다.

Sequence Diagram

sequenceDiagram
    participant Developer
    participant GooglePlayStore
    participant EndUserDevice

    Developer->>APK: Sign APK with Developer's Private Key
    APK->>GooglePlayStore: Upload APK (signed by Developer)
    GooglePlayStore->>APK: Verifies APK using Developer's Certificate
    EndUserDevice->>APK: Downloads APK from Play Store
    EndUserDevice->>APK: Verifies APK using Developer's Certificate (in APK)
Enter fullscreen mode Exit fullscreen mode

new school signing sequence diagram

  1. 개발자가 자신의 private key(app signing key)로 APK를 서명한다.
  2. 서명된 APK를 Google Playstore에 업로드한다.
  3. Playstore가 개발자의 인증서(app signing certificate)로 APK의 서명을 검증한다.
  4. 최종 사용자가 Playstore에서 APK를 다운로드한다.
  5. 최종 사용자의 기기가 APK에 포함된 개발자의 인증서로 APK의 서명을 검증한다.

문제점

개발자가 자신의 private key(app signing key)를 잃어버렸을 때, reset할 수 있는 방법이 없다. 따라서 private key를 잃어버리면 앱을 업데이트할 수 없게 된다. 이런 문제를 해결하기 위하여 새로운 방식이 등장하게 된다.

New-School (App Signing By Google Play)

최종 사용자의 기기에서 앱을 검증할 때 Google Play의 private key로 signing한 app에 대하여 검증하는 방식이다. 최종 유저에게 app을 서명할 때 Google Play에서 만든 private key로 사용하기 때문에, 개발자는 자신의 private key를 잃어버리더라도 Google Play에게 조치를 받을 수 있다.

Sequence Diagram

sequenceDiagram
    participant Developer
    participant GooglePlayStore
    participant EndUserDevice

    Developer->>APK: Sign APK with Upload Key
    APK->>GooglePlayStore: Upload APK (signed by Developer)
    GooglePlayStore->>APK: Verifies APK using Developer's Certificate
    GooglePlayStore->>APK: Re-signs APK with Google Play's Private Key
    EndUserDevice->>APK: Downloads APK from Play Store (signed by Google)
    EndUserDevice->>APK: Verifies APK using Google's Certificate (in APK)
Enter fullscreen mode Exit fullscreen mode

new school signing sequence diagram

  1. 개발자가 자신의 private key(upload key)로 APK를 서명한다.
  2. 서명된 APK를 Playstore에 업로드한다.
  3. Playstore가 개발자의 인증서(upload certificate)로 APK의 서명을 검증한다.
  4. Playstore가 Google Play의 private key(app signing key)로 APK를 다시 서명한다.
  5. 최종 사용자가 Playstore에서 Google Play이 서명한 APK를 다운로드한다.
  6. 최종 사용자의 기기가 APK에 포함된 Google 인증서(app signing certificate)로 APK의 서명을 검증한다.

출처

https://docs.expo.dev/app-signing/app-credentials/

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.