Code Signing — What It Is, Code Signing and How It Works

Author: IT Sectr Published: 2026-04-16 Reading time: 9 min

Code Signing (code signing) is a digital signature mechanism for executable files that guarantees developer authenticity and application integrity. In Android, every APK file must be signed with a certificate before installation on a device or publication on Google Play. According to Google, 2024, Android supports four generations of signing schemes: from v1 based on JAR to v4 for streaming installation.

Key Takeaways

  • Code Signing — a digital signature of code that confirms authorship and application integrity.
  • In Android, signing is performed through a keystore — a key and certificate storage.
  • The v2 (APK Signature Scheme) is the main standard since Android 7.0, protecting all bytes of the APK.
  • Key rotation (v3, Android 9.0+) allows changing the signing key without deleting the application.
  • Google Play uses Play App Signing for centralized key management.

What is Code Signing?

Code Signing is a cryptographic process in which a developer signs executable code with their digital certificate. The signature is created using asymmetric encryption: the developer’s private key generates a digital signature, and the public key is embedded in the certificate. Anyone can verify the signature using the public key, but modifying the code without breaking the signature is impossible.

In mobile development, code signing serves three functions. First — authentication: the user and platform can identify the application developer. Second — integrity: any change to the APK after signing invalidates the signature. Third — trusted updates: the platform only allows updating an application with APKs signed by the same certificate as the installed version.

Legal Status

Digital signing of Android applications has legal significance. According to Russian legislation (63-FZ) and the European eIDAS, a qualified electronic signature is equivalent to a handwritten one. However, signing an APK with a self-signed certificate (common practice in Android) is not qualified — it confirms integrity but not the developer’s identity from a legal standpoint.

Android Signing Schemes: v1, v2, v3, v4

Android supports four APK signing schemes, each solving the problems of the previous version and adding new capabilities. All schemes can coexist in a single APK — this is necessary for backward compatibility with older Android versions.

The v1 (JAR signing) scheme appeared in Android 1.0. It signs individual files inside the APK archive using entries in META-INF/MANIFEST.MF. The drawback: an attacker can modify the APK (add or remove files) and re-sign only the changed ones without touching the rest. This makes v1 vulnerable to certain attacks. The v2 (APK Signature Scheme), introduced in Android 7.0, signs the entire APK file as a whole, including all bytes except the signature itself, eliminating the possibility of selective modification.

SchemeAndroidFeatureKey Rotation
v1 (JAR)1.0+Per-file signingNo
v27.0+Full APK signingNo
v39.0+Signing + rotationYes
v411.0+Streaming + ADBYes

v3: Signing Key Rotation

Scheme v3, introduced in Android 9.0, solves a long-standing problem: what to do if the signing key is compromised or expired? Previously, changing the signing key meant the application was treated as a new one — it could not be installed over an existing one. v3 adds a rotation mechanism: the APK can include proof-of-rotation, signed by the old key. The system verifies the chain and allows updating the application signed with the new key.

Keystore and Certificates

Keystore is a secure container that holds private keys and certificates for signing applications. Android development uses JKS (Java KeyStore) or PKCS12 format. The keystore is created with the keytool utility, which is part of the JDK. Each key in the store is identified by an alias and protected by a password.

The certificate in a keystore contains the public key and owner information: organization name, country, validity period. For Android applications, the certificate can be self-signed — Google does not require a certificate authority (CA), which distinguishes Android from iOS. However, the certificate validity must be at least 25 years, since the application will be updated with the same key.

bash
# Creating a new keystore for signing
keytool -genkey -v -keystore my-release.keystore \
        -alias my-app-alias \
        -keyalg RSA \
        -keysize 2048 \
        -validity 10000

# Viewing keystore contents
keytool -list -v -keystore my-release.keystore

Key Formats

Android supports two algorithms for signing keys: RSA and ECDSA. RSA with a 2048-bit key size is the de facto standard, supported by all Android versions. ECDSA (Elliptic Curve Digital Signature Algorithm) with the P-256 curve provides the same cryptographic strength with a smaller key size. Since Android 9.0, ECDSA is recommended because it is faster in verification on mobile devices.

Configuring Signing in Build

In Android Gradle Plugin, signing is configured through the signingConfigs block in the module-level build.gradle. For debug builds, Android Studio automatically creates a debug keystore with known passwords. For release builds, the developer specifies the path to their keystore, the key alias, and passwords. It is recommended to store passwords in separate configuration files excluded from version control.

A modern practice is centralized signing management through CI/CD. Jenkins, GitLab CI, or GitHub Actions can store the keystore as a protected artifact and passwords as environment secrets. This prevents key leakage through the repository and simplifies key rotation when necessary.

groovy
// build.gradle (app-level) — signing configuration
android {
    signingConfigs {
        release {
            storeFile file("my-release.keystore")
            storePassword System.getenv("KEYSTORE_PASSWORD")
            keyAlias System.getenv("KEY_ALIAS")
            keyPassword System.getenv("KEY_PASSWORD")
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

Multi-Scheme Signing

For maximum compatibility, an APK should be signed with all three schemes (v1 + v2 + v3). Android Gradle Plugin enables all schemes by default. APKs signed only with v2 will not install on Android 6.0 and below. APKs with only v1 will not get the integrity benefits of v2 on Android 7.0+. Enabling all schemes does not increase APK size by more than 1–2% and ensures compatibility with any device.

Play App Signing and Key Management

Play App Signing is a Google Play service that centrally manages application signing keys. The developer uploads an APK signed with an upload key to Google Play Console, and Google Play re-signs it with a distribution key before delivering it to users. This protects the distribution key from loss or compromise.

Benefits of Play App Signing: security — the distribution key is stored in Google’s secure storage; rotation — you can request a key change through the console; recovery — if the upload key is lost, a new one can be generated. The downside: for applications that existed before Play App Signing was introduced, migration requires creating a new application, since the old distribution key is already in use.

bash
# Getting the certificate fingerprint (SHA-256)
keytool -list -v -keystore my-release.keystore \
        -alias my-app-alias | grep "SHA256"

# Verifying APK signature with apksigner
apksigner verify --verbose app-release.apk

Key Recovery

If the signing key is lost and Play App Signing is not used, it is impossible to restore the ability to update the application — you will have to create a new application with a new package name. This is one of the main reasons to use Play App Signing. Google recommends keeping a backup copy of the keystore in a secure offline storage (encrypted USB drive, bank safe deposit box).

Signature Verification on the Device

When installing an APK, Android performs signature verification in several stages. First — certificate check: whether the validity has expired and the format is correct. Second — signature verification: whether the cryptographic signature matches the APK contents. Third — certificate comparison with the installed version: if the application already exists on the device, the certificate must match, otherwise installation is blocked.

The verification system is built into PackageManagerService. When processing an installation request, PMS extracts the signature from the APK, verifies it using the android.util.PackageParser class, and compares it with the stored signature of the installed application (if it exists). If they do not match, the user gets the error “INSTALL_FAILED_UPDATE_INCOMPATIBLE”. This mechanism prevents substitution attacks (malware cannot replace a legitimate application with its own version).

Developer Verification

A developer can independently verify the APK signature using the apksigner utility from Android SDK Build Tools. The command apksigner verify --verbose app.apk shows which schemes the APK is signed with, whether the certificates are valid, and whether the signatures match the contents. For programmatic verification of an installed application’s signature, use PackageManager.getPackageInfo() with the GET_SIGNATURES flag.

kotlin
// Programmatic signature verification of an installed application
fun getAppSignature(context: Context, packageName: String): String? {
    val pm = context.packageManager
    val info = pm.getPackageInfo(
        packageName,
        PackageManager.GET_SIGNATURES
    )
    return info.signatures?.firstOrNull()?.toCharsString()
}

Best Practices for Signing Security

Signing key security is a critical aspect of Android development. Key compromise allows an attacker to sign updates to your application with their own code. The main rules: never store the key in a repository, do not use one key for multiple applications, do not transfer the key through unsecured channels (email, messengers).

The recommended practice is key separation. Use a separate key for each application and a separate key for uploading to Google Play (upload key). For debug builds, Android Studio creates a shared debug.keystore — it must not be used for release builds. The certificate validity should be 25–30 years (current standard, confirmed by Google).

PracticeRecommendation
Key storageEncrypted medium, CI/CD secrets
Certificate validityAt least 25 years
AlgorithmRSA 2048+ or ECDSA P-256
SeparationSeparate key per application
BackupOffline keystore copy

Signature Audit

Regularly check the signing chain integrity. When employees with key access leave, update the upload key through Google Play Console. Use tools like Google Play Integrity API to verify that your application has not been tampered with on user devices. The API returns data about the signature and integrity, sending it to the server for verification.

Frequently Asked Questions

What is Code Signing in Android?

Code Signing is a digital signature of an APK file that confirms the application was created by a specific developer and has not been modified after signing. Without a signature, the APK will not install on a device.

How do I create a key for signing an Android application?

Use the keytool utility from the JDK: keytool -genkey -v -keystore my-release.keystore -alias my-alias -keyalg RSA -keysize 2048 -validity 10000. Specify the resulting keystore in build.gradle in the signingConfigs block.

What happens if I lose the signing key?

If the key is lost and you are not using Play App Signing, updating the application becomes impossible. You will have to create a new application on Google Play with a new package name. Use Play App Signing to protect against key loss.

What is the difference between v1 and v2 signing schemes?

v1 signs each file inside the APK individually — an attacker can modify one file and re-sign only that one. v2 signs the entire APK as a whole — any change invalidates the signature, providing a higher level of security.

What is Play App Signing?

Play App Signing is a Google Play service that centrally stores the application distribution key. The developer uploads an APK signed with an upload key, and Google re-signs it before delivery to users, protecting the key from loss or theft.

Summary

  • Code Signing is a mandatory digital signature for APKs, guaranteeing application authenticity and integrity.
  • Android supports four signing schemes: v1 (JAR), v2 (APK Signature), v3 (key rotation), and v4 (streaming).
  • Keystore is a secure key container created via keytool with RSA 2048+ algorithm.
  • Key rotation (v3, Android 9.0+) allows changing the signing key without deleting the application.
  • Play App Signing centrally manages distribution keys through Google Play Console.
  • Signature verification during installation blocks substitution attacks: certificate mismatch = INSTALL_FAILED error.
  • Key security: separate key per application, 25+ year validity, offline copy, no keys in the repository.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also