To sign an APK from the command line, you create a key once with keytool, run zipalign on the unsigned APK, then sign it with apksigner sign --ks your-key.jks app.apk. Finish with apksigner verify to confirm the signature. The order is the part people get wrong: align first, sign second, and change nothing after signing.
What you need
- keytool, which comes with the Java JDK.
- apksigner and zipalign from the Android SDK Build Tools. The apksigner docs say the tool is in Build Tools revision 24.0.3 and higher.
- An unsigned or debug APK, for example the release output from a Gradle build with no signing config.
If you’re not sure why the unsigned file won’t install in the first place, signed vs unsigned APKs covers that.
Step 1: Create a signing key (once)
keytool -genkeypair -v -keystore release.jks -keyalg RSA -keysize 2048 -validity 9125 -alias release
According to the keytool reference, -genkeypair creates a key pair, wraps the public key in a self-signed certificate and stores both under the alias you give. Two defaults are worth overriding. -validity is counted in days and defaults to 90, far too short for an app. And if you skip -alias, the key is stored as mykey, which you’ll forget.
The AndroidIDE signing tutorial uses 9125 days, which is 25 years. That lines up with Google’s app signing guidance: the key should be valid for at least 25 years, and for Google Play the validity has to end after 22 October 2033.
The keytool docs also note that since JDK 9 the default keystore type is PKCS12, even if the file is named .jks.
Step 2: Align the APK
zipalign -P 16 -f -v 4 app-unsigned.apk app-aligned.apk
The zipalign docs explain that alignment lets Android read uncompressed files straight from the archive with mmap, which cuts memory use. The -P 16 flag aligns any .so native libraries to a 16KiB page boundary so they work on both 16KiB and 4KiB devices. The older -p flag is deprecated.
If the APK came out of Android Studio or the Android Gradle plugin, it’s already aligned. You can check with:
zipalign -c -P 16 -v 4 app-aligned.apk
Step 3: Sign it
apksigner sign --ks release.jks --ks-key-alias release --out app-signed.apk app-aligned.apk
--ks-key-alias is required when the keystore holds more than one key.
Without --out, apksigner signs in place and overwrites the input APK. Fine in a script, annoying when you wanted to keep the aligned copy.
The password is read from stdin by default, so you get a prompt. For CI, set --ks-pass to env:KEY_PASS or file:pass.txt. Avoid pass:..., which leaves the password in your shell history.
Step 4: Verify
apksigner verify -v --print-certs app-signed.apk
This confirms the signature will verify on every Android version the APK supports and prints the certificate details. Run it every time. If it fails, don’t ship the file.
What goes wrong
Running zipalign after signing. Both the apksigner and zipalign docs say any change after apksigner signs the file invalidates the signature. The zipalign page notes the opposite order only applies to jarsigner, which it describes as not recommended.
Signing an update with a new key. Android only installs an update if its certificate matches the installed app’s. A fresh keytool run on a new laptop gives you a different key, and the phone reports a failed install. The causes behind that message are in why an APK says “App not installed”.
Losing the keystore. The signing docs are blunt: if Google Play doesn’t hold your app signing key and you lose yours, you can’t update the app, and a key can’t be regenerated. Copy release.jks and its password somewhere other than the machine you built on.
If you’d rather not touch a terminal
WebToAPK Free builds a signed APK and an AAB in the browser. The key is created and used there, protected by a password of at least 10 characters, and it isn’t uploaded to a build server. The signing and updates guide explains how to back it up.
The limitation: it can’t import an existing JKS or P12 keystore, only its own encrypted key backups. An app you already signed with the steps above has to keep getting its updates signed that way.
My take
I’d put steps 2 to 4 in a small script on day one, with the password read from an environment variable. Signing by hand is easy to get right once and easy to get wrong the fifth time, usually by forgetting --out or aligning in the wrong order. If you’re still deciding whether a converter is safe to hand your key to, see whether online website-to-APK converters are safe.
FAQ
Do I need Android Studio to sign an APK?
No. You need keytool, which ships with the JDK, and apksigner and zipalign from the Android SDK Build Tools. apksigner is in Build Tools 24.0.3 and higher.
Should I run zipalign before or after apksigner?
Before. Any change to the APK after apksigner signs it invalidates the signature. Only the older jarsigner tool expects zipalign after signing.
How do I check that an APK is signed?
Run apksigner verify with –print-certs on the file. It reports whether the signature will verify on the Android versions the APK supports and prints the signing certificate details.
Can I use jarsigner instead of apksigner?
Android’s zipalign docs describe jarsigner as not recommended. Use apksigner, which the Android docs use in their own examples.