Signing Your Android APK: From Keystore to Google Play
If you've built an Android app and want to release it on Google Play, you'll need to sign your APK. This comprehensive guide walks you through the entire signing process—from generating your keystore to managing your signing credentials in Google Play.
Why Sign Your APK?
APK signing serves two critical purposes:
- Authenticity: It proves to Android that you're the legitimate developer of the app
- Integrity: It ensures the APK hasn't been modified after signing
Google Play and Android devices require valid signatures before installation. Without proper signing, your app simply won't run on devices.
Step 1: Generate Your Keystore
A keystore is a binary file containing your private signing key. Think of it as your app's digital passport—keep it safe, because losing it means you can't update your app on Google Play.
Using keytool Command
keytool -genkey -v -keystore my-release-key.keystore \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias my-key-alias
What each flag means:
-
-genkey: Generate a new key pair -
-v: Verbose output -
-keystore: Output file name -
-keyalg RSA: Use RSA algorithm (industry standard) -
-keysize 2048: 2048-bit encryption (minimum recommended) -
-validity 10000: Valid for ~27 years -
-alias: Internal name for this key
The command will prompt for:
- Keystore password (e.g.,
MySecurePass123!) - Key password (can be same as keystore password)
- Your name, organization, location
Example output:
Generating 2,048 bit RSA key pair and self-signed certificate...
Enter keystore password: ****
Re-enter new password: ****
What is your first and last name?
[Unknown]: John Developer
What is the name of your organizational unit?
[Unknown]: Mobile Apps
What is the name of your organization?
[Unknown]: MyCompany Inc
What is the name of your City or Locality?
[Unknown]: San Francisco
What is the name of your State or Province?
What is the two-letter country code for this location?
After completion, you'll have my-release-key.keystore file ready.
Step 2: Configure Signing in build.gradle.kts
Store your keystore securely and reference it in your Gradle build configuration. Create a local.properties file in your project root:
KEYSTORE_PATH=/Users/you/keys/my-release-key.keystore
KEYSTORE_PASSWORD=MySecurePass123!
KEY_ALIAS=my-key-alias
KEY_PASSWORD=MySecurePass123!
Do not commit this file to version control! Add it to .gitignore:
local.properties
Now update your build.gradle.kts:
android {
signingConfigs {
create("release") {
// Load signing credentials from local.properties
val localProperties = Properties()
val localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localProperties.load(localPropertiesFile.inputStream())
}
storeFile = file(localProperties.getProperty("KEYSTORE_PATH", ""))
storePassword = localProperties.getProperty("KEYSTORE_PASSWORD", "")
keyAlias = localProperties.getProperty("KEY_ALIAS", "")
keyPassword = localProperties.getProperty("KEY_PASSWORD", "")
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
Full build.gradle.kts example:
import java.util.*
plugins {
id("com.android.application")
kotlin("android")
}
android {
namespace = "com.example.myapp"
compileSdk = 34
defaultConfig {
applicationId = "com.example.myapp"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0.0"
}
signingConfigs {
create("release") {
val localProperties = Properties()
val localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localProperties.load(localPropertiesFile.inputStream())
}
storeFile = file(localProperties.getProperty("KEYSTORE_PATH", ""))
storePassword = localProperties.getProperty("KEYSTORE_PASSWORD", "")
keyAlias = localProperties.getProperty("KEY_ALIAS", "")
keyPassword = localProperties.getProperty("KEY_PASSWORD", "")
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
}
Step 3: Build Signed Release APK
Once configured, building a signed APK is simple:
./gradlew assembleRelease
This creates a signed APK at:
app/build/outputs/apk/release/app-release.apk
Verify the signature:
jarsigner -verify -verbose app-release.apk
Output should show:
sm 1234 Fri Feb 28 14:32:10 PST 2026 AndroidManifest.xml
sm 5678 Fri Feb 28 14:32:10 PST 2026 classes.dex
...
jar verified.
Step 4: Google Play App Signing
Google Play now manages app signing certificates through "App Signing by Google Play." Here's how it works:
- You upload an APK signed with your upload key
- Google Play re-signs it with your app signing key (stored securely by Google)
- The re-signed APK is distributed to devices
This separation adds security—even if your upload key is compromised, your app signing key remains protected by Google.
Uploading to Google Play Console
- Navigate to Google Play Console
- Select your app
- Go to Release > Production
- Click Create new release
- Upload your signed APK:
app-release.apk - Review and confirm
- Roll out to production
Step 5: Keystore Backup Best Practices
Your keystore is irreplaceable. Losing it means:
- You can't update your app on Google Play
- You must publish a completely new app with a new package name
- Users lose access to app data and reviews
Backup Strategy
- Store securely: Use encrypted cloud storage (Google Drive, iCloud, OneDrive with encryption)
- Multiple copies: Keep backups in 2-3 locations
- Password management: Store the keystore password separately from the keystore itself
- Version control: Do NOT commit to Git
Backup command:
cp my-release-key.keystore ~/Backups/my-release-key.keystore
cp my-release-key.keystore /path/to/encrypted/cloud/storage/
Export Keystore Info
Save your keystore details to a secure document:
keytool -list -v -keystore my-release-key.keystore
This shows:
- Creation date
- Expiration date
- Certificate fingerprint (SHA-256)
- Alias and key details
Store this document alongside your password manager backup.
Troubleshooting Common Issues
Error: "keystore tampered with, or password was incorrect"
Cause: Wrong password or corrupted keystore file
Solution: Verify the password and file integrity. Restore from backup if necessary.
Error: "Certificate chain is not complete"
Cause: Missing intermediate certificates
Solution: Use keytool to regenerate or verify the certificate chain
APK rejected by Google Play: "Invalid signature"
Cause: Keystore mismatch or corrupted APK
Solution: Regenerate the APK using the correct keystore
Summary
Android APK signing is a one-time setup that takes just a few minutes:
- Generate keystore with keytool
- Configure signing in build.gradle.kts
- Build signed APK with
./gradlew assembleRelease - Upload to Google Play Console
- Secure your keystore with backups
Once set up, your signing configuration is ready to use for every release. Keep your keystore safe, and your app will stay secure and updatable for years to come.
My 8 templates come with signing-ready build configs. https://myougatheax.gumroad.com
Top comments (0)