Skip to content
intermediate Phase 13 · Play Store & Production

App Signing

Understand keystore management, upload keys, and Google Play App Signing.

35m
0 problems
Topic Progress 0%

Android App Signing Fundamentals

Why Apps Must Be Signed

Every Android APK must be cryptographically signed before it can be installed. Signing proves the author's identity and ensures the APK has not been tampered with since it was published. Play Store, sideload installs, and enterprise deployments all require a valid signature.

Keystore and Key Types

An Android keystore is a file containing a collection of cryptographic keys. When you sign an APK, you use a private key from a keystore to generate a digital signature. The corresponding public key is embedded in the APK for verification.

There are two key roles in the signing lifecycle:

  1. App signing key — The key that permanently signs the APK at install time. Once set on the Play Store, it cannot be changed.
  2. Upload key — A separate key used to sign the AAB/APK before uploading to Play Console. This key can be rotated if compromised.

Signing Levels

Android introduced new signing schemes over time:

Scheme Min SDK Changes
v1 (JAR) 1 Basic JAR signing
v2 (APK Signature Scheme v2) N (24) Full APK file verification
v3 (APK Signature Scheme v3) R (30) Key rotation support
v4 (APK Signature Scheme v4) S+ Incremental install support

Debug vs Release Signing

During development, Android Studio automatically signs with a debug keystore. For production, you generate a release keystore:

# Generate a release keystore with keytool
keytool -genkeypair -v \
  -keystore my-release-key.jks \
  -keyalg RSA -keysize 2048 \
  -validity 10000 \
  -alias my-key

You will be prompted for a password and Distinguished Name fields. Store the keystore file and password securely — losing them means you can never update your published app.

Configuring Signing in Gradle

Signing Configuration in build.gradle.kts

The signingConfigs block in Gradle defines which keystore to use for each build type:

android {
    signingConfigs {
        create("release") {
            storeFile = file("../keystore/my-release-key.jks")
            storePassword = System.getenv("KEYSTORE_PASSWORD")
            keyAlias = System.getenv("KEY_ALIAS")
            keyPassword = System.getenv("KEY_PASSWORD")
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true
            signingConfig = signingConfigs.getByName("release")
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

Never Hardcode Credentials

Avoid committing keystore passwords to version control. Use environment variables or a local keystore.properties file excluded from Git:

# keystore.properties (add to .gitignore)
storeFile=../keystore/my-release-key.jks
storePassword=your_store_password
keyAlias=my-key
keyPassword=your_key_password
// Load from keystore.properties
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = java.util.Properties().apply {
    if (keystorePropertiesFile.exists()) {
        load(keystorePropertiesFile.inputStream())
    }
}

android {
    signingConfigs {
        create("release") {
            storeFile = file(keystoreProperties["storeFile"] as String)
            storePassword = keystoreProperties["storePassword"] as String
            keyAlias = keystoreProperties["keyAlias"] as String
            keyPassword = keystoreProperties["keyPassword"] as String
        }
    }
}

Verifying Your Signing

After building, verify the APK signature:

# Check APK signing info
apksigner verify --print-certs app-release.apk

# Verify all signing schemes
apksigner verify --verbose --print-certs app-release.apk

Google Play App Signing

How Google Play App Signing Works

When you enable Google Play App Signing, Play Console manages your app signing key. The flow becomes:

  1. You sign your AAB/APK with your upload key
  2. Google verifies your upload signature
  3. Google re-signs the APK with your app signing key
  4. The app signing key is used for all distribution

This separation means:

  • If your upload key is compromised, you can request a new one from Play Console
  • Your app signing key is stored in Google's hardware security modules (HSM)
  • You can opt into key upgrades (v2 to v3 signing) for key rotation

Enrolling in Google Play App Signing

When creating a new app in Play Console, you are prompted to enroll. For existing apps:

  1. Go to Setup > App integrity in Play Console
  2. Click App signing key certificate to view your certificate
  3. Download the certificate to share with partners who need to verify your signature

Upload Key Reset

If you lose your upload key, you can request a reset through Play Console:

  1. Go to Setup > App integrity
  2. Click Request upload key reset
  3. Upload a new upload certificate (public key only)
  4. Google will revoke the old upload key and accept the new one

This is a critical safety net that makes losing your upload key recoverable — unlike losing the original app signing key when not using Play App Signing.

Export and Key Migration

When migrating to Play App Signing, Google imports your existing app signing key. You generate a new upload key and begin signing uploads with it. The original signing key is transferred into Google's HSM infrastructure.

Quiz

1. What happens if you lose the app signing key for a published app on Google Play?

Question 1 options

2. Which signing scheme introduced full APK file verification rather than just JAR entries?

Question 2 options

3. What is the primary advantage of using an upload key separate from the app signing key?

Question 3 options

4. Why should keystore passwords never be hardcoded in build.gradle.kts?

Question 4 options

Flashcards

Question

What is the difference between an upload key and an app signing key?

Answer

The upload key signs the AAB before uploading to Play Console and can be rotated. The app signing key permanently signs the APK for distribution and cannot be changed.

Question

What does APK Signature Scheme v2 improve over v1?

Answer

V2 verifies the entire APK file rather than individual JAR entries, providing stronger integrity guarantees and faster verification.

Question

What command verifies an APK's signing certificate?

Answer

apksigner verify --print-certs app-release.apk

Question

How does Google Play App Signing protect against upload key loss?

Answer

Play Console allows you to request an upload key reset, uploading a new public key while the original app signing key stays in Google's HSM.

Revision Notes

Key Takeaways

  • 1. Every Android APK must be cryptographically signed before installation
  • 2. Use an upload key separate from your app signing key for Play Store uploads
  • 3. Google Play App Signing stores your signing key in Google's HSM and allows upload key rotation
  • 4. Always store keystores and passwords securely — losing the app signing key means you cannot update your app
  • 5. APK Signature Scheme v2+ verifies the full APK, not just JAR entries

Interview Tips

  • Be able to explain the difference between debug and release signing
  • Know why Play App Signing is recommended for production apps
  • Discuss what happens when a signing key is compromised
  • Understand the purpose of each APK signature scheme version

Cheat Sheet

App Signing Cheat Sheet

Keystore: File containing cryptographic keys for signing
Upload key: Signs AAB for Play Console upload; can be rotated
App signing key: Signs APK for distribution; permanent

Signing Schemes:

  • v1: JAR signing (all API levels)
  • v2: Full APK verification (API 24+)
  • v3: Key rotation support (API 30+)
  • v4: Incremental install (API S+)

Generate Keystore:

keytool -genkeypair -v -keystore release.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key

Verify Signing:

apksigner verify --print-certs app-release.apk

Never hardcode keystore passwords — use environment variables or a .gitignore'd keystore.properties file.