286

I have an app which is signed and several keystore files. I'd like to update the app, so I need to find out which one of keys was used.

How can I match which keystore was used to originally sign my app against various keystores I have on my machine?

Maarten Bodewes
  • 80,169
  • 13
  • 121
  • 225
xliiv
  • 4,509
  • 5
  • 26
  • 33
  • I have no idea can you find it or not, but if you sign app with wrong key, developer console(where you publish apps) will tell you that it is wrong. You can try them all. – logcat Jul 04 '12 at 15:03
  • There is an public key 'developer console' > 'Edit Profile'. Can i use it anyhow to help myself? – xliiv Jul 04 '12 at 15:06
  • how to recreate the keystore file if it got deleted accidentally? – Maveňツ Mar 14 '17 at 07:25
  • @Maveňツ you can't. If you loose your keystore, you are toast. Google did introduce [App Signing], where they hold on to the signing information. [App Signing]: https://support.google.com/googleplay/android-developer/answer/7384423?hl=en – mir May 15 '19 at 00:53

6 Answers6

440

First, unzip the APK and extract the file /META-INF/ANDROID_.RSA (this file may also be CERT.RSA, but there should only be one .RSA file).

Then issue this command:

keytool -printcert -file ANDROID_.RSA

You will get certificate fingerprints like this:

     MD5:  B3:4F:BE:07:AA:78:24:DC:CA:92:36:FF:AE:8C:17:DB
     SHA1: 16:59:E7:E3:0C:AA:7A:0D:F2:0D:05:20:12:A8:85:0B:32:C5:4F:68
     Signature algorithm name: SHA1withRSA

Then use the keytool again to print out all the aliases of your signing keystore:

keytool -list -keystore my-signing-key.keystore

You will get a list of aliases and their certificate fingerprint:

android_key, Jan 23, 2010, PrivateKeyEntry,
Certificate fingerprint (MD5): B3:4F:BE:07:AA:78:24:DC:CA:92:36:FF:AE:8C:17:DB

Voila! we can now determined the apk has been signed with this keystore, and with the alias 'android_key'.

Keytool is part of Java, so make sure your PATH has Java installation dir in it.

azgolfer
  • 14,494
  • 4
  • 46
  • 46
  • 1
    Thank you for this. I added a tool for doing this to my github project. https://github.com/RichardBronosky/ota-tools/blob/master/apk_fingerprint – Bruno Bronosky Aug 01 '14 at 19:43
  • Hi I don't understand this command ~ keytool -list -keystore my-signing-key.keystore , what's my-signing-key.keystore – Thoman Nov 06 '15 at 10:45
  • 2
    @Thoman my-signing-key.keystore is the name of the keystore file containing the keys that are used to sign the apk – 1800 INFORMATION Mar 21 '16 at 23:30
  • Thanks a lot for this! Our app was re-signed by PlayStore and it causes Google login to fail. I had to download the APK directly from PlayStore and find the actual SHA1 to register it in the Google Cloud console. – Alvin Rusli Jan 04 '18 at 06:36
  • 1
    Google has introduced [two new APK signature schemes](https://source.android.com/security/apksigning), neither of which use traditional JAR signing with an embedded file. `keytool` cannot read these signatures. Use [apksigner](https://stackoverflow.com/a/57830572/798224) instead. – Phil Calvin Oct 16 '20 at 16:28
386

You can use Java 7's Key and Certificate Management Tool keytool to check the signature of a keystore or an APK without extracting any files.

Signature of an APK or AAB

# APK file
keytool -printcert -jarfile app.apk

# AAB file
keytool -printcert -jarfile app.aab

The output will reveal the signature owner/issuer and MD5, SHA1 and SHA256 fingerprints of the APK file app.apk or AAB file app.aab.

(Note that the -jarfile argument was introduced in Java 7; see the documentation for more details.)

Signature of a keystore

keytool -list -v -keystore release.jks

The output will reveal the aliases (entries) in the keystore file release.jks, with the certificate fingerprints (MD5, SHA1 and SHA256).

If the SHA1 fingerprints between the APK and the keystore match, then you can rest assured that that app is signed with the key.

Paul Lammertsma
  • 35,234
  • 14
  • 128
  • 182
  • 1
    @goRGon Are you using Java 7 or later? – Paul Lammertsma Jun 03 '14 at 21:19
  • No. Java 7 brought too many problems =) So it works only on Java 7? Could you please mention it inside your answer? – goRGon Jun 03 '14 at 21:31
  • 2
    @goRGon Indeed, the `-jarfile` argument was introduced with Java 7. I've updated the answer. – Paul Lammertsma Jun 04 '14 at 09:53
  • 49
    This should be an accepted answer. No unzipping needed – Jacek Kwiecień Jun 19 '14 at 09:19
  • If this worked with the Java shipped with the current MacOS, it would be the be THE answer. Until then it's another answer. Let's face it, if you are doing Android dev, you are also doing iOS dev. (upvoted still) – Bruno Bronosky Aug 01 '14 at 19:40
  • 1
    It's odd that Java 1.6 is still shipped by default on Mac. I'd recommend updating to a more recent version. – Paul Lammertsma Aug 25 '14 at 18:27
  • 2
    @RichardBronosky That's not true indeed. I have been an Android developer for more than three years without doing iOS dev. Though, I agree with your main point for different reasons. Java 1.6 seems to be the most extended version so far, or at least widespread, and whilst the accepted solution works with both 1.6 and 1.7, this one will only work with 1.7, so I don't think this should be the accepted answer (yet!). (Also note that the accepted answer is form 2012, whilst this one is from April, 2014) – Fran Marzoa Oct 19 '14 at 14:42
  • I had the issue with google Maps v2 because I uploaded the release.apk but on my Android Studio when I used `keytool -list -v -keystore keystore.jks -alias alias -storepass storepass -keypass keypass` I received the debug SHA1 and not the release one. With `keytool -list -printcert -jarfile app.apk` I fixed everything. Thanks @Paul Lammertsma – Alexiscanny May 03 '16 at 09:57
  • I was able to execute it using java 1.6 without any problems. – Machado Jan 10 '18 at 13:14
  • 3
    This also works for Android app bundle .aab files :-) – LordParsley Aug 19 '19 at 13:49
18

To build on Paul Lammertsma's answer, this command will print the names and signatures of all APKs in the current dir (I'm using sh because later I need to pipe the output to grep):

find . -name "*.apk" -exec echo "APK: {}" \; -exec sh -c 'keytool -printcert -jarfile "{}"' \;

Sample output:

APK: ./com.google.android.youtube-10.39.54-107954130-minAPI15.apk
Signer #1:

Signature:

Owner: CN=Unknown, OU="Google, Inc", O="Google, Inc", L=Mountain View, ST=CA, C=US
Issuer: CN=Unknown, OU="Google, Inc", O="Google, Inc", L=Mountain View, ST=CA, C=US
Serial number: 4934987e
Valid from: Mon Dec 01 18:07:58 PST 2008 until: Fri Apr 18 19:07:58 PDT 2036
Certificate fingerprints:
         MD5:  D0:46:FC:5D:1F:C3:CD:0E:57:C5:44:40:97:CD:54:49
         SHA1: 24:BB:24:C0:5E:47:E0:AE:FA:68:A5:8A:76:61:79:D9:B6:13:A6:00
         SHA256: 3D:7A:12:23:01:9A:A3:9D:9E:A0:E3:43:6A:B7:C0:89:6B:FB:4F:B6:79:F4:DE:5F:E7:C2:3F:32:6C:8F:99:4A
         Signature algorithm name: MD5withRSA
         Version: 1

APK: ./com.google.android.youtube_10.40.56-108056134_minAPI15_maxAPI22(armeabi-v7a)(480dpi).apk
Signer #1:

Signature:

Owner: CN=Unknown, OU="Google, Inc", O="Google, Inc", L=Mountain View, ST=CA, C=US
Issuer: CN=Unknown, OU="Google, Inc", O="Google, Inc", L=Mountain View, ST=CA, C=US
Serial number: 4934987e
Valid from: Mon Dec 01 18:07:58 PST 2008 until: Fri Apr 18 19:07:58 PDT 2036
Certificate fingerprints:
         MD5:  D0:46:FC:5D:1F:C3:CD:0E:57:C5:44:40:97:CD:54:49
         SHA1: 24:BB:24:C0:5E:47:E0:AE:FA:68:A5:8A:76:61:79:D9:B6:13:A6:00
         SHA256: 3D:7A:12:23:01:9A:A3:9D:9E:A0:E3:43:6A:B7:C0:89:6B:FB:4F:B6:79:F4:DE:5F:E7:C2:3F:32:6C:8F:99:4A
         Signature algorithm name: MD5withRSA
         Version: 1

Or if you just care about SHA1:

find . -name "*.apk" -exec echo "APK: {}" \; -exec sh -c 'keytool -printcert -jarfile "{}" | grep SHA1' \;

Sample output:

APK: ./com.google.android.youtube-10.39.54-107954130-minAPI15.apk
         SHA1: 24:BB:24:C0:5E:47:E0:AE:FA:68:A5:8A:76:61:79:D9:B6:13:A6:00
APK: ./com.google.android.youtube_10.40.56-108056134_minAPI15_maxAPI22(armeabi-v7a)(480dpi).apk
         SHA1: 24:BB:24:C0:5E:47:E0:AE:FA:68:A5:8A:76:61:79:D9:B6:13:A6:00
Artem Russakovskii
  • 20,170
  • 17
  • 87
  • 114
  • Interesting! I've used a very similar approach in a validation on our privately hosted distribution store to inform the user that the app was not signed correctly. I also take special note to observe if the key alias is "androiddebugkey" to display a differently worded message. I think Google Play does validation in much the same way. I suppose you're using this to validate APKs on APKMirror? – Paul Lammertsma Jan 20 '16 at 10:49
  • @PaulLammertsma Yes, we are. – Artem Russakovskii Feb 01 '16 at 04:05
12

Much easier way to view the signing certificate:

jarsigner.exe -verbose -verify -certs myapk.apk

This will only show the DN, so if you have two certs with the same DN, you might have to compare by fingerprint.

Nikolay Elenkov
  • 51,084
  • 9
  • 81
  • 82
  • What is DN? Mostly i got many lines like this: X.509, CN={firstname and lastname} [certificate is valid from {date from} to {date_to}] – xliiv Jul 05 '12 at 08:34
  • DN stands for 'Distinguished Name', in your case it's the 'CN={firstname and lastname}' part. – Nikolay Elenkov Jul 05 '12 at 08:42
9

You can do this with the apksigner tool that is part of the Android SDK:

apksigner verify --print-certs my_app.apk

You can find apksigner inside the build-tools directory. For example: ~/Library/Android/sdk/build-tools/29.0.1/apksigner

Nic Dahlquist
  • 805
  • 11
  • 13
  • 1
    `apksigner` does not print the certificates for *split* apks (those that come with the **base.apk** for an app distributed as a bundle (**aab**); the `keytool` does. – Alex Cohn Nov 16 '20 at 08:35
6

There are many freewares to examine the certificates and key stores such as KeyStore Explorer.

Unzip the apk and open the META-INF/?.RSA file. ? shall be CERT or ANDROID or may be something else. It will display all the information associated with your apk.

wpcoder
  • 860
  • 8
  • 15
Hanif
  • 176
  • 1
  • 5