Skip to main content

Overview

Android requires all APKs and AABs to be digitally signed before installation. This ensures app authenticity and enables secure updates. TechSales uses different signing configurations for debug and release builds.

Debug vs Release Signing

Debug Signing

Debug builds are automatically signed with a debug keystore:
  • Location: ~/.android/debug.keystore
  • Password: android
  • Alias: androiddebugkey
  • Valid for: Development only
Never use the debug keystore for production releases. Apps signed with debug keys cannot be published to Google Play Store.

Release Signing

Release builds require a production keystore that you create and manage securely.

Generating a Release Keystore

1

Create Keystore Directory

Create a secure location for your keystore:
mkdir -p ~/keystores
cd ~/keystores
2

Generate Keystore

Use keytool to generate a new keystore:
keytool -genkey -v -keystore techsales-release.jks \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -alias techsales-key
You’ll be prompted to enter:
  • Keystore password (choose a strong password)
  • Key password (can be same as keystore password)
  • Your name and organization details
3

Verify Keystore

Confirm the keystore was created successfully:
keytool -list -v -keystore techsales-release.jks
Critical: Back up your keystore file and passwords securely. If you lose your release keystore, you cannot update your app on Google Play Store.

Configuring Signing in Gradle

Update app/build.gradle.kts to include signing configuration:
android {
    namespace = "com.teamtech.techsales"
    compileSdk {
        version = release(36) {
            minorApiLevel = 1
        }
    }

    signingConfigs {
        create("release") {
            storeFile = file("../keystores/techsales-release.jks")
            storePassword = System.getenv("KEYSTORE_PASSWORD")
            keyAlias = "techsales-key"
            keyPassword = System.getenv("KEY_PASSWORD")
        }
    }

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

Storing Credentials Securely

Never commit keystore passwords or the keystore file itself to version control.

Using Environment Variables

Set environment variables before building:
export KEYSTORE_PASSWORD="your_keystore_password"
export KEY_PASSWORD="your_key_password"
./gradlew assembleRelease

Using gradle.properties

Create gradle.properties in your project root (add to .gitignore):
KEYSTORE_PASSWORD=your_keystore_password
KEY_PASSWORD=your_key_password
KEYSTORE_FILE=../keystores/techsales-release.jks
KEY_ALIAS=techsales-key
Update build.gradle.kts:
signingConfigs {
    create("release") {
        storeFile = file(project.property("KEYSTORE_FILE") as String)
        storePassword = project.property("KEYSTORE_PASSWORD") as String
        keyAlias = project.property("KEY_ALIAS") as String
        keyPassword = project.property("KEY_PASSWORD") as String
    }
}

Using Android Studio

Android Studio provides a UI for signing:
  1. Build > Generate Signed Bundle / APK
  2. Select AAB or APK
  3. Choose existing keystore or create new
  4. Enter passwords
  5. Select build variant (release)

Google Play App Signing

Google Play App Signing is recommended for managing your app signing key securely.
With Google Play App Signing:
  • Google manages your app signing key
  • You upload an AAB signed with an upload key
  • Google re-signs with the app signing key
  • You can reset lost upload keys

Enrollment

  1. Upload your first release AAB to Google Play Console
  2. Opt in to Google Play App Signing
  3. Google generates or imports your app signing key
  4. Download the upload key certificate for future updates

Verifying Signed APKs

Check the signature of your signed APK:
jarsigner -verify -verbose -certs app-release.apk
View detailed certificate information:
apksigner verify --print-certs app-release.apk

Key Management Best Practices

1

Backup Keystores

Store keystore files in multiple secure locations:
  • Encrypted cloud storage
  • Secure password manager
  • Offline encrypted USB drive
2

Document Credentials

Record in a secure location:
  • Keystore location
  • Keystore password
  • Key alias
  • Key password
  • Validity dates
3

Restrict Access

  • Limit keystore access to authorized team members
  • Use role-based access in CI/CD systems
  • Audit keystore usage regularly
4

Monitor Expiry

  • Track keystore validity period (10,000 days = ~27 years)
  • Plan for key rotation if needed
  • Ensure keys remain valid for app lifetime
Security Checklist:
  • ✓ Keystore backed up in 3+ locations
  • ✓ Passwords stored in secure password manager
  • ✓ Keystore file excluded from version control
  • ✓ Environment variables used for CI/CD
  • ✓ Google Play App Signing enabled

CI/CD Signing

For automated builds, store credentials securely: GitHub Actions:
- name: Build Release AAB
  env:
    KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
    KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
  run: ./gradlew bundleRelease
GitLab CI:
build:release:
  script:
    - ./gradlew bundleRelease
  variables:
    KEYSTORE_PASSWORD: $KEYSTORE_PASSWORD
    KEY_PASSWORD: $KEY_PASSWORD
For complete build instructions, see Building Release APKs/AABs.

Build docs developers (and LLMs) love