55

If I have an apk can I remove the current signing and some how re-sign it with a different .keystore file and still have the application install?

Update: I managed to get it to work with Jorgesys' solution and where I messed up before was that I unzipped the .apk then rezipped it after removing the META-INF folder and changed the file extension back into .apk. What I should have done is simply opened it with winzip and delete the folder inside of winzip.

Clyde Lobo
  • 9,126
  • 7
  • 34
  • 61
Anton
  • 12,285
  • 20
  • 64
  • 84

7 Answers7

76

try this

1) Change the extension of your .apk to .zip

2) Open and remove the folder META-INF

3) Change the extension to .apk

4) Use the jarsigner and zipalign with your new keystore.

hope it helps

Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • I gave that a go, but when I try to install the app it throws a parse exception. – Anton Jul 16 '10 at 19:01
  • hi Anton post your stacktrace – Jorgesys Jul 16 '10 at 19:55
  • i posted the result in my question – Anton Jul 16 '10 at 20:23
  • Sounds like you deleted `AndroidManifest.xml` from the root of the APK file, rather than only the `META-INF`. – Christopher Orr Jul 16 '10 at 20:33
  • 1
    hehe =) java.io.FileNotFoundException: AndroidManifest.xml – Jorgesys Jul 16 '10 at 20:43
  • Nope I didn't. I did exactly those 4 steps. – Anton Jul 17 '10 at 00:35
  • Well I don't really have experience with what you're doing, but the /data directory has permissions 770, so you can't even list the contents of the /data directory. – Falmarri Jul 17 '10 at 06:15
  • if you want a quick solution just check out my answer http://stackoverflow.com/a/16146126/700869 – Aksel Fatih Jan 03 '14 at 10:43
  • This is what does vendor script [sign_target_files_apks](https://github.com/android/platform_build/blob/master/tools/releasetools/sign_target_files_apks) (well, it works with zip archive of target files). – pevik Jul 02 '14 at 06:18
  • 3
    1-3 steps is just = zip -d foo.apk META-INF/\* – k4dima Jan 17 '16 at 20:59
  • @Elenasys thanks for your solotion . its work But i have a problem : I want change manifest from apk file and use itself meta-info folder , i need to re-sign an .apk with a different apk certificate , for example sign my app with facebook certification . is it possible ? – mohammad Jul 04 '16 at 12:08
  • 1
    This will not work with apks signed with the new v2 signing schema https://source.android.com/security/apksigning/v2.html – Patrick Nov 18 '16 at 15:34
  • How the heck do you do number 3 – arled Oct 11 '17 at 11:17
  • 6
    **NOTE:** This *wont't* work with [APK signing schema v2](https://source.android.com/security/apksigning/v2) (~2017) – Patrick Feb 03 '18 at 08:04
32

If you are looking for a quick simple solution, you can use Google's apksigner command line tool which is available in revision 24.0.3 and higher.

apksigner sign --ks release.jks application.apk

You can find more information about apksigner tool, at the developer Android site.

https://developer.android.com/studio/command-line/apksigner.html

Or, alternatively, you may use an open-source apk-resigner script

Open Source apk-resigner script https://github.com/onbiron/apk-resigner

All you have to do is, download the script and just type:

   ./signapk.sh application.apk keystore key-pass alias
Aksel Fatih
  • 1,419
  • 18
  • 31
12

Note if you use v2 signing schema (which you will automatically if you use build-tools 24.0.3+ in AS) you cannot just remove the META-INF folder from the APK since v2 adds its signing data to a zip meta block.

Google's new apksigner introduced in build-tools 24.03 (Android 7) is however able to resign APKs. You can just repeat the signing command to sign with a new keystore/cert (the old ones will be removed).

apksigner sign --ks keystore.jks signed_app.apk

Shameless plug: if you want a easier tool that can sign multiple apks and has better log output use: https://github.com/patrickfav/uber-apk-signer (uses Google's apksigner.jar in the background)

Patrick
  • 33,984
  • 10
  • 106
  • 126
10
zip -d my_application.apk META-INF/\*
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore my_application.apk alias_name
zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk
k4dima
  • 6,070
  • 5
  • 41
  • 39
7

Signing for release: $1.apk -> $1_release.apk" GeneralMills&GoogleApps#2012 Step 1: Removing any previous signing Change the extension of your .apk to .zip Open and delete the folder META-INF Change the extension to .apk Or Command: • zip [originalapk] Example: • zip "$1".apk -d

Step 2: Signing with release.keystore.. Command: • jarsigner –verbose –keystore [keystorefile] –signedjar [unalignedapk] [originalapk] alias_name Example: • C:\Program Files\Java\jdk1.6.0_43\bin> jarsigner -verbose -keystore release.keystore -signedjar "$1"_unaligned.apk "$1".apk release

Step 3: Aligning Command: • zipalign -f 4 [unalignedapk] [releaseapk] Example: • C:\Users\G535940\Downloads\adt-bundle-windows-x86\adt-bundle-windows-x86\sdk\too ls>zipalign -f 4 "$1"_unaligned.apk "$1"_release.apk

Step 4: Cleaning up Command: • rm 4 [unalignedapk] Example: • rm "$1"_unaligned.apk

Additional Commands might help:

  1. To generate new key with keytool keytool -genkey -alias -keystore

  2. To list keys keytool -list -keystore

Command to generate a keyhash for the Facebook features

Command: • keytool -exportcert -alias alias_name -keystore [keystorefile] | openssl sha1 -binary | openssl base64

Example: • C:\Program Files\Java\jdk1.6.0_43\bin>keytool -exportcert -alias release -keyst ore release.keystore |opens l sha1 -binary | openssl base64

Note: To sign our apks we have downgraded JDK from 1.7 to 1.6.0_43 update.

Reason: As of JDK 7, the default signing algorithim has changed, requiring you to specify the signature and digest algorithims (-sigalg and -digestalg) when you sign an APK.

Command: jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore [keystorefile] [originalapk] alias_name

Vihana Kewalramani
  • 915
  • 11
  • 14
3

All the solutions above work. Just a note why it didn't work for you when you re-zipped:

Some of the files inside the .apk need to remain stored (compression at 0%). This is because Android will use memory mapping (mmap) to read the contents without unpacking into memory. Such files are .ogg and some of the icons.

gilm
  • 7,690
  • 3
  • 41
  • 41
  • 1
    Just experienced this ... if you rezip APK completely, it will lead to inexplicably weird behavior. APK can be installed, APP may/may not start up, but will freeze eventually when it hits mmap code that is zipped. – Kefik Sep 15 '14 at 13:20
3

Assuming your keys are stored in keys.keystore, you can run:

$ keytool -list -keystore keys.keystore
Your keystore contains 1 entry

your_key_alias, Jan 3, 2013, PrivateKeyEntry, 
Certificate fingerprint (SHA1): 8C:C3:6A:DC:7E:B6:12:F1:4C:D5:EE:F1:AE:17:FB:90:89:73:50:53

to determine the alias of your key. Then run:

zip -d your_app.apk "META-INF/*"
jarsigner -verbose -keystore keys.keystore \
   -sigalg MD5withRSA -digestalg SHA1 -sigfile CERT \
   your_app.apk your_key_alias

to re-sign your_app.apk with the key named your_key_alias.

The extra -sigfile CERT option seems to be necessary as of JDK 8.

Phil Calvin
  • 5,077
  • 2
  • 41
  • 35