161

I've decoded an APK with apktool (as the original source code was lost) so I could fix some issues with the layout xml files. I've then rebuilt it back up with apktool and when I tried to install it on my device (using adb: adb install appname.apk) it gave me this error:

[INSTALL_PARSE_FAILED_NO_CERTIFICATES]

the original apk however was signed by a keystore (on eclipse IDE), this one isn't, how can I sign it properly with it's original keystone file outside Eclipse!?

Patrick
  • 33,984
  • 10
  • 106
  • 126
svarog
  • 9,477
  • 4
  • 61
  • 77
  • 1
    yeah, the whole point of certificates is to stop people from doing this... If you don't have the original cert you are gonna have to regenerate one – edthethird Jun 08 '12 at 02:37
  • that's just it, i have the original cert, but decoding/re-building the apk removed it. – svarog Jun 10 '12 at 10:11
  • 1
    Note: All answers to this question that make use of `jarsigner` are outdated. APKs signed by jarsigner will not be accepted by recent Android versions (AFAIR Android 10+). You need to use `apksigner` from Android SDK. – Robert May 13 '23 at 12:18

6 Answers6

378

create a key using

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

then sign the apk using :

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore my_application.apk alias_name

check here for more info

Benjamin Trent
  • 7,378
  • 3
  • 31
  • 41
user3854546
  • 3,804
  • 1
  • 12
  • 4
  • 1
    if you do this and try to install the APK, you might end up with a INSTALL_FAILED_DUPLICATE_PERMISSION error. This happens when the original APK cannot be overwrited (system or built-in app for instance) – Couitchy Jan 14 '16 at 18:43
  • @Couitchy adb shell pm install -r /data/tmp/myapk.apk – Dr Deo Apr 20 '16 at 16:22
  • 18
    if you dont want to bother creating a key you can use the debug key with: jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ~/.android/debug.keystore app.apk androiddebugkey -storepass android – Pellet Sep 19 '16 at 01:31
  • 3
    Is there a difference between using `jarsigner` and `apksigner`? One requires signing and then zipaligning and the other zipaligning and then signinig – Maria Ines Parnisari Dec 15 '16 at 17:27
  • Debug key lives only 1 year since SDK installation, so it is not a good idea to use it for a release. – snuk182 Feb 13 '17 at 15:26
  • What is the Difference between Jar signer and Apk signer? https://stackoverflow.com/questions/44153144/what-is-the-difference-between-jar-signer-and-apk-signer – James Wilkins May 01 '18 at 22:50
  • For Windows I couldn't find jarsigner but I did find apksigner.bat in the Android Studio sdk folder, which did work great. ;) Perhaps this is the NEW way? Anyhow, the file was in `C:\Users\{username}\AppData\Local\Android\Sdk\build-tools\{version}` for Android Studio and also in `C:\Program Files (x86)\Android\android-sdk\build-tools\{version}` (or similar path) for Visual Studio 2017 users. – James Wilkins May 01 '18 at 22:52
  • Would like to nominate this for best answer on Stack overflow – nmu Aug 31 '18 at 13:37
  • Thanks a lot, I was looking for how to specify an alias, the documentation was confusing and does not provide clear examples. – michael-martinez Oct 23 '20 at 09:08
  • getting Error: `Only one alias can be specified` – Parth Developer Oct 14 '21 at 08:04
  • There's the error I'm getting when running `jarsigner`: jarsigner: unable to sign jar: java.util.zip.ZipException: invalid entry compressed size (expected 2025 but got 1897 bytes) – Shimmy Weitzhandler Oct 26 '21 at 05:11
  • `keytool -genkey -v -keystore xxxrelease.jks -alias xxxrelease -keyalg RSA -keysize 2048 -validity 10000` and after run `jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore xxxrelease.jks OppoSignVerify.apk xxxrelease` works this way for me. I just copied .jsk file from my android project – Vadim Eremeev Feb 18 '23 at 05:47
127

Automated Process:

Use this tool (uses the new apksigner from Google):

https://github.com/patrickfav/uber-apk-signer

Disclaimer: I'm the developer :)

Manual Process:

Step 1: Generate Keystore (only once)

You need to generate a keystore once and use it to sign your unsigned apk. Use the keytool provided by the JDK found in %JAVA_HOME%/bin/

keytool -genkey -v -keystore my.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias app

Step 2 or 4: Zipalign

zipalign which is a tool provided by the Android SDK found in e.g. %ANDROID_HOME%/sdk/build-tools/24.0.2/ is a mandatory optimization step if you want to upload the apk to the Play Store.

zipalign -p 4 my.apk my-aligned.apk

Note: when using the old jarsigner you need to zipalign AFTER signing. When using the new apksigner method you do it BEFORE signing (confusing, I know). Invoking zipalign before apksigner works fine because apksigner preserves APK alignment and compression (unlike jarsigner).

You can verify the alignment with

zipalign -c 4 my-aligned.apk

Step 3: Sign & Verify

Using build-tools 24.0.3 and newer

Android 7.0 introduces APK Signature Scheme v2, a new app-signing scheme that offers faster app install times and more protection against unauthorized alterations to APK files (See here and here for more details). Therefore, Google implemented their own apk signer called apksigner (duh!) The script file can be found in %ANDROID_HOME%/sdk/build-tools/24.0.3/ (the .jar is in the /lib subfolder). Use it like this

apksigner sign --ks-key-alias alias_name --ks my.keystore my-app.apk

and can be verified with

apksigner verify my-app.apk

The official documentation can be found here.

Using build-tools 24.0.2 and older

Use jarsigner which, like the keytool, comes with the JDK distribution found in %JAVA_HOME%/bin/ and use it like so:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my.keystore my-app.apk my_alias_name

and can be verified with

jarsigner -verify -verbose my_application.apk
Robert
  • 39,162
  • 17
  • 99
  • 152
Patrick
  • 33,984
  • 10
  • 106
  • 126
  • 2
    For build-tools 24.0.3 correct way to call zipalign is: zipalign -p 4 my.apk my-aligned.apk – kinORnirvana Apr 28 '17 at 18:00
  • Thanks for your description! tried uber-apk-signer first but failed probably because I have openJDK installed on my system instead of oracles "official" java. So I tried the manual way and also failed (still same error `[INSTALL_PARSE_FAILED_NO_CERTIFICATES]`). Verifying with uber-apk-signer gave me some further insight `signature VERIFY FAILED` [...] `ERROR: JAR signer CERT.RSA: JAR signature META-INF/CERT.RSA uses digest algorithm 2.16.840.1.101.3.4.2.1 and signature algorithm 1.2.840.113549.1.1.1 which is not supported on API Levels [[15, 17]]`. Yes, android 4.2.2, SHA256 not there? ideas? – antiplex Jul 19 '17 at 16:29
  • @antiplex please report the issue in github not SO – Patrick Dec 08 '17 at 13:59
  • @for3st do you mean that my issues may not be due to my limited knowledge around apk-signing but due to some form of incompatibility of uber-apk-signer? but even then the manual way also fails which seems unrelated to your tool... – antiplex Feb 12 '18 at 07:30
  • For those looking for the command line tool location, I found it in `C:\Users\{username}\AppData\Local\Android\Sdk\build-tools\{version}` for Android Studio and also in `C:\Program Files (x86)\Android\android-sdk\build-tools\{version}` (or similar path) for Visual Studio 2017 users. – James Wilkins May 01 '18 at 22:56
  • `zipalign -p 4 my.apk my-aligned.apk` says `ERROR: unknown flag -p`. – user2513149 Feb 09 '19 at 11:51
  • Seems like `--ks-key-alias` is not needed, if there's only key in a keystore. – Velda Aug 20 '20 at 09:04
  • The following command worked for me: `zipalign 4 my.apk my-aligned.apk` (without the `-p` option). – user2513149 Jan 26 '21 at 15:19
  • Did you set up env variable for apksigner? I am getting command not found – Rohit Singh Aug 27 '22 at 23:42
17

fastest way is by signing with the debug keystore:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ~/.android/debug.keystore app.apk androiddebugkey -storepass android

or on Windows:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore %USERPROFILE%/.android/debug.keystore test.apk androiddebugkey -storepass android
Doug
  • 6,446
  • 9
  • 74
  • 107
Pellet
  • 2,254
  • 1
  • 28
  • 20
  • jarsigner is deprecated and should no longer be used. APKs signed by jarsigner will not work on recent Andorid versions. – Robert Aug 25 '23 at 16:49
6

You use jarsigner to sign APK's. You don't have to sign with the original keystore, just generate a new one. Read up on the details: http://developer.android.com/guide/publishing/app-signing.html

Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
4

For those of you who don't want to create a bat file to edit for every project, or dont want to remember all the commands associated with the keytools and jarsigner programs and just want to get it done in one process use this program:

http://lukealderton.com/projects/programs/android-apk-signer-aligner.aspx

I built it because I was fed up with the lengthy process of having to type all the file locations every time.

This program can save your configuration so the next time you start it, you just need to hit Generate an it will handle it for you. That's it.

No install required, it's completely portable and saves its configurations in a CSV in the same folder.

Luke Alderton
  • 3,198
  • 1
  • 23
  • 34
  • Does not work for me. No certificate is added to APK. Seems like it does nothing. Do not even ask for an alias password. – Velda Aug 20 '20 at 08:32
3

Updated answer

Check https://shatter-box.com/knowledgebase/android-apk-signing-tool-apk-signer/

Old answer

check apk-signer a nice way to sign your app

Yogesh Rathi
  • 6,331
  • 4
  • 51
  • 81
shereifhawary
  • 463
  • 4
  • 13