Nemax
Nemax

Reputation: 391

Signature error msg when uploading new APK version (SHA1 not supported in API level 8)

I have published an app in 2010. Back then, I had created a local keystore and one key, which I have never changed and used for all my (about 30) versions of this app which I have published since then.

I never had any issues with this, it always worked fine, back in the days when I developed with Eclipse, neither the last few years when I switched to Android Studio.

The last version I published 2016-12-23. Now I wanted to publish a new one, generated a signed APK with Android Studio, uploaded it to Developer Console... and got the following error message:

Upload failed - You uploaded an APK with an invalid signature (learn more about signing). Error from apksigner: ERROR (Jar signer CERT.DSA): JAR signature META-INF/CERT.DSA uses digest algorithm SHA-1 and signature algorithm SHA-1 with DSA which is not supported on API Level(s) 8 for which this APK is being verified

I tried these combinations of the (newly available) signature version options (always with the same result):

I am using Android Studio 2.3.3 with buildToolsVersion 25.0.0 and Gradle version 3.3.

Upvotes: 5

Views: 2262

Answers (1)

Alex Klyubin
Alex Klyubin

Reputation: 5732

The error message you're seeing is that this APK won't install on Android Froyo (API Level 8). The APK's JAR signature (META-INF/CERT.DSA) uses OID 1.2.840.10040.4.3 (SHA-1 with DSA) to specify the signature algorithm. This OID is supported on Android in JAR signatures only from API Level 9 but your APK's AndroidManifest.xml specifies -- via android:minSdkVersion attribute -- that the APK supports API Level 8. For DSA, the best signature algorithm OID to use in JAR signature is 1.2.840.10040.4.1 (DSA, not SHA-1 with DSA). The resulting cryptographic signature is exactly the same, it's just that this OID is supported in JAR signatures by all Android versions. Signing tools normally don't provide this level of control though, but they are supposed to pick a working OID.

Android Studio, Android Plugin for Gradle, and apksigner are all supposed to produce correctly signed APKs unless you specify custom parameters. For example, does your build.gradle file specify minSdkVersion 9 or higher by any chance? Or, perhaps, you're release-signing the APK using jarsigner which doesn't know about Android rules...

Ideas:

  • If you're release-signing using jarsigner, switch to apksigner or use Android Studio / Android Plugin for Gradle for release signing. For example, to re-sign an APK using apksigner:

    apksigner sign --ks my.keystore app.apk
    
  • If you're release-signing using Android Studio / Android Plugin for Gradle, in your build.gradle file, specify the same minSdkVersion as in the AndroidManifest.xml. Alternatively, perhaps, dropping minSdkVersion from build.gradle file will make Android Studio / Android Plugin for Android use the minSdkVersion from AndroidManifest.xml? I'm somewhat dubious about this because Android Studio 2.3.3 is supposed to use the correct/safe OID 1.2.840.10040.4.1 when signing such APKs...

  • Adjust minSdkVersion in AndroidManifest.xml to 9 or higher if you're fine with dropping support for Froyo.

P. S. To check whether your APK is properly signed and to see the errors that will likely be reported by Google Play at upload time:

apksigner verify my.apk

Upvotes: 3

Related Questions