When an Android app is signed, the signing process generates a unique digital signature for the app package file (APK). This signature is based on the contents of the APK and is designed to be difficult to forge. The signature is used to verify that the app has not been tampered with and that it was signed by the developer who claims to have signed it.

The signing process uses a private and public key pair, which is a fundamental component of public key cryptography. The private key is used to generate the digital signature, while the public key is used to verify the signature.

The private key used to sign the app is typically generated by the app developer using a tool such as keytool or OpenSSL. The private key should be kept secret and should only be accessible to the developer or a trusted agent. The public key, on the other hand, is included in the digital certificate that is generated when the APK is signed.

The digital certificate contains information about the app, such as the package name, version number, and the public key used to sign the APK. The certificate is also signed by a trusted certificate authority, such as Google, to ensure that the certificate itself is authentic.

When a user installs an app on their Android device, the Android operating system verifies the digital signature using the public key stored in the app's certificate. If the signature is valid and the certificate is trusted, the app is installed. If the signature is not valid or the certificate is not trusted, the installation is blocked.

The Android signing process also supports the concept of release keys and debug keys. A release key is used to sign the final version of an app that is published to an app store, while a debug key is used to sign test versions of the app during development. The debug key is typically generated automatically by the Android development tools and should not be used to sign the final version of the app.

Singing Versions

  1. JAR signing (v1 signing): This is the original signing mechanism used in Android apps. It was designed for Java Archives (JARs) and applied to Android APKs. It involves signing each entry in the APK individually, and a signature file (META-INF) is added to the APK. JAR signing has some limitations, such as the inability to detect changes in the APK after signing.
  2. APK Signature Scheme v2 (v2 signing): Introduced in Android 7.0 (Nougat), APK Signature Scheme v2 improves upon the v1 signing by signing the entire APK file, not just individual entries. This makes it easier to detect changes in the APK after signing, providing better security and integrity. To use v2 signing, you need to enable it in your app's build.gradle file or use Android Studio's "Generate Signed APK" wizard.
  3. APK Signature Scheme v3 (v3 signing): Introduced in Android 9.0 (Pie), APK Signature Scheme v3 further enhances the signing process by adding an additional layer of protection. It includes the app's certificate alongside the APK signatures, which allows Google Play to verify updates and installs with a single signing certificate, even if the app's signing key is lost or compromised.
  4. APK Signature Scheme v4 (v4 signing): While not yet widely adopted, APK Signature Scheme v4 is a proposed enhancement to the signing process. It aims to provide better performance and security by using a new file format and a more efficient signing algorithm. You can find more details about v4 signing in the Android Developers documentation.
  5. Android App Bundle (AAB) signing: Android App Bundles are a new app publishing format introduced in Android Studio 3.2. They allow developers to build and package their apps in a more efficient and modular way. When you upload an app bundle to Google Play, it is signed by Google using the app signing key, which provides an additional layer of security.

Signing V1

starting from Android 11, APK signature scheme v2 became mandatory, and jarsigner doesn't support signing APKs using this scheme. Instead, you can use the Android SDK Build Tools' apksigner tool to sign your APK.

keytool -genkey -v -keystore your_keystore_name.keystore -alias your_alias_name -keyalg RSA -keysize 2048 -validity 10000