Generated APK is not signed if signature v2 is selected
Asked Answered
H

2

7

I am trying to generate a signed APK for my app and it works if I only use signature V1. When I use signature V2 and then check apk with keytool, the output is:

keytool -list -printcert -jarfile app-release.apk
Not a signed jar file

Here is the build.gradle:

def getProps(path) {
    Properties props = new Properties()
    props.load(project.rootProject.file(path).newDataInputStream())
    return props
}

android {
    ...
    signingConfigs {
        debug {
            try {
                Properties props = getProps('./local.properties')
                storeFile file(props.getProperty('DEBUG_STORE_FILE', ''))
                keyAlias props.getProperty('DEBUG_KEY_ALIAS', '')
                keyPassword props.getProperty('DEBUG_STORE_PASSWORD', '')
                storePassword props.getProperty('DEBUG_STORE_PASSWORD', '')
                v1SigningEnabled true
                v2SigningEnabled false // enabling this generates unsigned apk
            }
            catch (ex) {
                throw new InvalidUserDataException("You should define RELEASE_STORE_FILE, RELEASE_KEY_ALIAS, RELEASE_STORE_PASSWORD in local.properties.")
            }
        }
        release {
            try {
                Properties props = getProps('./local.properties')
                storeFile file(props.getProperty('RELEASE_STORE_FILE', ''))
                keyAlias props.getProperty('RELEASE_KEY_ALIAS', '')
                keyPassword props.getProperty('RELEASE_STORE_PASSWORD', '')
                storePassword props.getProperty('RELEASE_STORE_PASSWORD', '')
                v1SigningEnabled true
                v2SigningEnabled false // enabling this generates unsigned apk
            }
            catch (ex) {
                throw new InvalidUserDataException("You should define RELEASE_STORE_FILE, RELEASE_KEY_ALIAS, RELEASE_STORE_PASSWORD in local.properties.")
            }
        }
    }

    defaultConfig {
        ...
        // Only productionRelease flavour uses signingConfigs.release;
        // other flavours(i.e. productionDebug, developmentDebug, developmentRelease)
        // use signingConfigs.debug
        // https://mcmap.net/q/66399/-gradle-signing-flavors-with-different-keys-on-android
        signingConfig signingConfigs.release
    }
    buildTypes {
        release {
            ...
        }
        debug {
            ...
            signingConfig signingConfigs.debug
        }
    }
    // Dimensions: environment can be one of [development, production]
    flavorDimensions "environment"
    productFlavors {
        development {
            ...
            signingConfig signingConfigs.debug
            ...
        }
        production {
            dimension "environment"
        }
    }
    ...
}

I also created a new Android project from scratch and it has the same issue.

Note that I have another Android project which can produce a signed APK selecting both V1 and V2.

Why adding signature V2 is causing the generation of an unsigned APK?

Husain answered 15/11, 2019 at 13:49 Comment(4)
what is your minSdkVersion ?Hiltonhilum
minSdkVersion 24, targetSdkVersion 27, compileSdkVersion 28Husain
btw as of today I cannot reproduce the issue with Android Studio 3.5.3 on Windows. I think I was using Android Studio 3.5.2 when I encountered it.Husain
I have encountered it with Android Studio 3.6.1, please see my post laterHiltonhilum
H
11

Signature v2 was introduced in Android 7.0 (24), so when your minSdkVersion is 24 or higher, enable both v1 and v2 like this:

signingConfigs {
        debug {
            v1SigningEnabled true
            v2SigningEnabled true
        }
    }

the signed apk will not have v1, it just signed with v2. This can be verified by apksigner like this:

java -jar apksigner.jar verify -v your-signed-apkfile.apk

enter image description here

Otherwise, keytool can not identify signature v2, so it prompt Not a signed jar file. And the signed apk with only signature v2 is also an available apk, it just can be installed on Android 7.0 or higher.

If you want signed with both v1 and v2, you should modify minSdkVersion to 23 or lower.

Hope it helps.

Hiltonhilum answered 9/3, 2020 at 13:20 Comment(1)
Indeed at time of writing question I had minsdk 24 and I was trying to understand why my gradle setup with both signing enabled had stopped working (for one of my two projects). It worked before I noticed the issue, so I disabled signing v1 as workaround. Now it works again with both signing.Husain
L
1

It's a bug from Android-Gradle-Plugin(AGP) when its version is below 4.0.0.

Here is the official description.

So there are two solutions:

  1. Keep your minSdkVersion to 23 or lower, like Euporie's answer

  2. Upgrade your AGP to 4.0.0 or higher.

    But please keep in mind that upgrading AGP usually need to upgrade buildToolsVersion and Gradle (in gradle-wrapper.properties if you are using gradleWrapper), sometimes even to upgrade JDK, synchronously.

    You can check AGP-Gradle-Compatibility and Gradle-JDK-Compatibility for detail version requirements.

Level answered 30/6, 2022 at 10:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.