24

Disclaimer: I know the basics of signing an APKs and I have a problem with only one of my projects and only when signing with Microsoft Windows as the OS.

I am building my APK with Maven and sign them with the maven-jarsigner-plugin:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jarsigner-plugin</artifactId>
    <executions>
      <execution>
        <id>signing</id>
        <goals>
          <goal>sign</goal>
        </goals>
        <phase>package</phase>
        <inherited>true</inherited>
        <configuration>
          <archive>target/${project.build.finalName}.apk</archive>
          <sigfile>CERT</sigfile>
          <keystore>${env.HOME}/.keystore</keystore>
          <storepass>${env.KEY_STOREPASS}</storepass>
          <keypass>${env.KEY_KEYPASS}</keypass>
          <alias>${env.KEY_ALIAS}</alias>
        </configuration>
      </execution>
    </executions>
  </plugin>

Now with one of my projects I get the following error when trying to install and start the application:

1360 KB/s (2057872 bytes in 1.477s)
        pkg: /data/local/tmp/FX-602P-Droid-5.0.0.apk
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]

As I said in the first sentence: It works fine when signing with Mac OS X. It only fails when using Windows 7 to sign.

Using --debug when calling Maven I see that the jarsigner is called ok and reports no error:

[INFO]
[INFO] --- maven-jarsigner-plugin:1.2:sign (signing) @ FX-602P-Droid ---
[DEBUG] org.apache.maven.plugins:maven-jarsigner-plugin:jar:1.2:
[DEBUG]    org.apache.maven:maven-plugin-api:jar:2.0.6:compile
[DEBUG]    org.apache.maven:maven-project:jar:2.0.6:compile
[DEBUG]       org.apache.maven:maven-settings:jar:2.0.6:compile
[DEBUG]       org.apache.maven:maven-profile:jar:2.0.6:compile
[DEBUG]       org.apache.maven:maven-model:jar:2.0.6:compile
[DEBUG]       org.apache.maven:maven-artifact-manager:jar:2.0.6:compile
[DEBUG]          org.apache.maven:maven-repository-metadata:jar:2.0.6:compile
[DEBUG]       org.apache.maven:maven-plugin-registry:jar:2.0.6:compile
[DEBUG]       org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile
[DEBUG]          junit:junit:jar:3.8.1:compile
[DEBUG]          classworlds:classworlds:jar:1.1-alpha-2:compile
[DEBUG]    org.apache.maven:maven-artifact:jar:2.0.6:compile
[DEBUG]    org.codehaus.plexus:plexus-utils:jar:1.5.15:compile
[DEBUG] Created new class realm plugin>org.apache.maven.plugins:maven-jarsigner-plugin:1.2
[DEBUG] Importing foreign packages into class realm plugin>org.apache.maven.plugins:maven-jarsigner-plugin:1.2
[DEBUG]   Imported:  < project>net.sourceforge.uiq3:FX-602P-Droid:5.0.0
[DEBUG] Populating class realm plugin>org.apache.maven.plugins:maven-jarsigner-plugin:1.2
[DEBUG]   Included: org.apache.maven.plugins:maven-jarsigner-plugin:jar:1.2
[DEBUG]   Included: junit:junit:jar:3.8.1
[DEBUG]   Included: org.codehaus.plexus:plexus-utils:jar:1.5.15
[DEBUG]   Excluded: org.apache.maven:maven-plugin-api:jar:2.0.6
[DEBUG]   Excluded: org.apache.maven:maven-project:jar:2.0.6
[DEBUG]   Excluded: org.apache.maven:maven-settings:jar:2.0.6
[DEBUG]   Excluded: org.apache.maven:maven-profile:jar:2.0.6
[DEBUG]   Excluded: org.apache.maven:maven-model:jar:2.0.6
[DEBUG]   Excluded: org.apache.maven:maven-artifact-manager:jar:2.0.6
[DEBUG]   Excluded: org.apache.maven:maven-repository-metadata:jar:2.0.6
[DEBUG]   Excluded: org.apache.maven:maven-plugin-registry:jar:2.0.6
[DEBUG]   Excluded: org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1
[DEBUG]   Excluded: classworlds:classworlds:jar:1.1-alpha-2
[DEBUG]   Excluded: org.apache.maven:maven-artifact:jar:2.0.6
[DEBUG] Configuring mojo org.apache.maven.plugins:maven-jarsigner-plugin:1.2:sign from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-jarsigner-plugin:1.
2, parent: sun.misc.Launcher$AppClassLoader@214c4ac9]
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-jarsigner-plugin:1.2:sign' with basic configurator -->
[DEBUG]   (f) alias = krischik
[DEBUG]   (f) archive = C:\Work\uiq3\Java\FX-602P-Droid\target\FX-602P-Droid-5.0.0.apk
[DEBUG]   (f) arguments = []
[DEBUG]   (f) keypass = Atlan.
[DEBUG]   (f) keystore = C:\Users\martin.krischik/.keystore
[DEBUG]   (f) processAttachedArtifacts = true
[DEBUG]   (f) processMainArtifact = true
[DEBUG]   (f) project = MavenProject: net.sourceforge.uiq3:FX-602P-Droid:5.0.0 @ C:\Work\uiq3\Java\FX-602P-Droid\pom.xml
[DEBUG]   (f) removeExistingSignatures = false
[DEBUG]   (f) sigfile = CERT
[DEBUG]   (f) skip = false
[DEBUG]   (f) storepass = !AtlanRhodan!
[DEBUG]   (f) verbose = false
[DEBUG] -- end configuration --
[DEBUG] Verarbeite C:\Work\uiq3\Java\FX-602P-Droid\target\FX-602P-Droid-5.0.0.apk
[DEBUG] 'cmd.exe /X /C "C:\opt\Java\jdk\1.7.0\bin\jarsigner.exe -keystore C:\Users\martin.krischik/.keystore -storepass '*****' -keypass '*****' -sigfile CERT C:\Work\u
iq3\Java\FX-602P-Droid\target\FX-602P-Droid-5.0.0.apk krischik"'
[INFO] 1 Archiv(e) verarbeitet
[INFO]

What else could have gone wrong?

PS: I just noted C:\opt\Java\jdk\1.7.0\bin\jarsigner.exe — Has there been a change to the jarsigner from 1.6 to 1.7? And why would Maven use the 1.7 signer for a 1.6 project?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Martin
  • 11,577
  • 16
  • 80
  • 110
  • **Update:** It is indeed a problem with the jarsigner. Using the 1.6 jar-signer from the command line works as expected. — So this becomes a maven question: how to specify which jarsigner to use in maven? – Martin Jan 05 '12 at 08:21
  • 1
    **Update:** The 1.7 jarsigner uses a different algorithm which is incompatible with Android. – Martin Jan 05 '12 at 13:26
  • 1
    This is tracked as a bug here http://code.google.com/p/android/issues/detail?id=19567 – Manfred Moser Jan 06 '12 at 20:42
  • But I think that this must be fixed in maven-jarsigner-plugin the same like it was fixed in ANT already, see: https://issues.apache.org/bugzilla/show_bug.cgi?id=52344 – ATom Mar 05 '12 at 12:19

4 Answers4

45

The solution is add this to the <configuration> of the maven-jarsigner-plugin:

<arguments>
  <argument>-sigalg</argument><argument>MD5withRSA</argument>
  <argument>-digestalg</argument><argument>SHA1</argument>
</arguments>

Ant already has direct support for this, but the Maven plugin does not.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ATom
  • 15,960
  • 6
  • 46
  • 50
10

It is very tricky to find info on the usage with 1.7, but once found it is reasonable simple:

For keytool include:

-sigalg SHA1withDSA -keyalg DSA -keysize 1024

For jarsigner include:

-sigalg SHA1withDSA -digestalg SHA1

(1024 is the maximum and works, less might do the trick)

Eske Rahn
  • 1,137
  • 12
  • 11
  • 1
    Not quite `jarsigner error: java.security.SignatureException: private key algorithm is not compatible with signature algorithm` – Martin Feb 06 '12 at 11:05
  • 1
    I got the same error as Martin when using these settings. Changing the `keytool` args to `-sigalg MD5withRSA -keyalg RSA -keysize 1024` worked for me. – vaughandroid Jun 01 '12 at 09:03
  • 1
    Baqueta, what if you want to use the original key and not generate a new one? I have the same problem as Martin – William Grand Nov 18 '13 at 21:33
2

The solution from Baqueta works also for me.

Use these arguments in the keytool:

-sigalg MD5withRSA -keyalg RSA -keysize 1024 

I am still using there in jarsigner:

-sigalg MD5withRSA -digestalg SHA1

Thank you, the APK compiled and installed on a device using Java 7, finally!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alejadro Xalabarder
  • 1,551
  • 19
  • 14
0

Thank you... It helped me in correcting signing issues...

jarsigner -verbose -sigalg SHA1withRSA -digestalg
keytool -sigalg MD5withRSA -keyalg RSA

Finally, don't forget to zipalign.

I used similar keytool and jarsigner methods and the issue was resolved.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131