Android certificate fingerprint is different although it shouldn't be

Today I tried to upload to the Play store an update to one of my Android games made with HaxeFlixel, and to my surprise Google says that the APK is signed with a different certificate. I have always used the same certificate file for quite some time, and did not make any major changes to the game, so I found this strange.

I submitted the previous update of this game a couple years ago, and have changed PC since, so it’s probably related. But I’m using the same versions of all haxetookit libraries. I’ve checked the fingerprint of the certificate I use and indeed it’s different from what Google says it should be. But the project.xml file points to this certificate (and always has), so I think only one of 2 things could have happened: another certificate was used previously (which I find hard to believe since I didn’t create any others and didn’t change anything relevant in the project), or previously when compiling the project the fingerprint of the certificate would change for some reason.

This is driving me nuts since it really doesn’t make any sense. I even checked the certificate fingerprint of another game I made in my previous PC and it’s the fingerprint Google says it should be, but when I compile the same project now, it gives the wrong fingerprint (but which is probably actually right, since it is the certificate’s SHA1 fingerprint; it’s probably when I was compiling it previously that something was going wrong. Any ideas? I’ve been using keytool and jarsigner to check the fingerprints. Thanks.

There is a debug certificate that we generate with Lime, which has been updated (since the old one expired) – we’ll have to do it again sometime, I’m not sure how long the certificate lasts.

Other than that, I can’t think of anything on our end that would affect the signing, except we have moved from Apache Ant to Gradle, and there’s a chance some old SDK or Ant script (provided by Google) wasn’t compatible somehow with something newer.

Do you have any project or computer that is compiling things to the older fingerprint? Do you think the other game you made also (possibly) used another certificate?

Where can I find the debug certificate generated with Lime?

I have also confirmed that the old APK seems to use the same certificate as the new one, because I get this for the old one (with correct fingerprint):

C:\Program Files\Java\jdk1.8.0_65\bin>jarsigner -verify -verbose:summary -certs 1000002.apk

sm      1428 Mon Aug 31 21:23:42 BST 2015 assets/assets/data/CPMStar.swf (and 220 more)

      X.509, CN=SelfSigned, O=Vasco Freitas
      [certificate is valid from 27-02-2011 0:29 to 27-02-2036 0:29]
      [CertPath not validated: Path does not chain with any of the trust anchors]

s      19795 Thu Oct 22 03:36:24 BST 2015 META-INF/MANIFEST.MF

      X.509, CN=SelfSigned, O=Vasco Freitas
      [certificate is valid from 27-02-2011 0:29 to 27-02-2036 0:29]
      [CertPath not validated: Path does not chain with any of the trust anchors]

       19848 Thu Oct 22 03:36:24 BST 2015 META-INF/CERT.SF (and 1 more)

      (Signature related entries)


  s = signature was verified
  m = entry is listed in manifest
  k = at least one certificate was found in keystore
  i = at least one certificate was found in identity scope

jar verified.

Warning:
This jar contains entries whose certificate chain is not validated.
This jar contains signatures that does not include a timestamp. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (2036-02-27) or after any future revocation date.

And the following when I generate an APK now (wrong fingerprint):

C:\Program Files\Java\jdk1.8.0_65\bin>jarsigner -verify -verbose:summary -certs G-Switch2-release.apk

sm      3348 Thu Mar 30 21:51:56 BST 2017 AndroidManifest.xml (and 240 more)

      X.509, CN=SelfSigned, O=Vasco Freitas
      [certificate is valid from 27-02-2011 0:29 to 27-02-2036 0:29]
      [CertPath not validated: Path does not chain with any of the trust anchors]

s      22073 Thu Mar 30 21:51:58 BST 2017 META-INF/MANIFEST.MF

      X.509, CN=SelfSigned, O=Vasco Freitas
      [certificate is valid from 27-02-2011 0:29 to 27-02-2036 0:29]
      [CertPath not validated: Path does not chain with any of the trust anchors]

       22126 Thu Mar 30 21:51:58 BST 2017 META-INF/CERT.SF (and 1 more)

      (Signature related entries)


  s = signature was verified
  m = entry is listed in manifest
  k = at least one certificate was found in keystore
  i = at least one certificate was found in identity scope

jar verified.

Warning:
This jar contains entries whose certificate chain is not validated.
This jar contains signatures that does not include a timestamp. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (2036-02-27) or after any future revocation date.

The certificates are valid from the exact same dates, doesn’t that mean they should be the same?

I don’t have any project or computer compiling things to the older fingerprint… The other game should have used the same certificate, I’ve been using the same file, and have checked that it is indeed the same.

Have you compared using the following commands? (source)

keytool -list -printcert -jarfile original.apk
keytool -list -printcert -jarfile update.apk

I think that will print additional signature information to compare the keys

Thanks for the command, that makes it easier to compare APK’s.

For the original APK I got:

Signer #1:

Signature:

Owner: CN=SelfSigned, O=Vasco Freitas
Issuer: CN=SelfSigned, O=Vasco Freitas
Serial number: 636366636163393a31326536343835333665353a2d38303030
Valid from: Sun Feb 27 00:29:35 GMT 2011 until: Wed Feb 27 00:29:35 GMT 2036
Certificate fingerprints:
         MD5:  E2:B3:A3:95:24:7B:D6:22:24:62:52:0A:70:B0:23:50
         SHA1: BD:DD:6C:5E:A9:40:F7:22:97:EC:A1:1A:94:4D:3A:E0:87:09:87:C2
         SHA256: 31:51:DE:0B:16:3F:BA:3F:F0:BC:4A:87:94:C0:99:12:3F:BA:9B:F8:7D:22:46:43:2E:F6:25:84:47:12:75:DB
         Signature algorithm name: SHA1withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  codeSigning
]

For the update:

Signer #1:

Signature:

Owner: CN=SelfSigned, O=Vasco Freitas
Issuer: CN=SelfSigned, O=Vasco Freitas
Serial number: 636366636163393a31326536343835333665353a2d38303030
Valid from: Sun Feb 27 00:29:35 GMT 2011 until: Wed Feb 27 00:29:35 GMT 2036
Certificate fingerprints:
         MD5:  AC:3F:61:85:18:EE:55:80:6B:47:DB:D8:2A:E4:D4:6D
         SHA1: A9:CD:F2:4D:3A:E0:28:64:31:67:E7:91:6E:27:D9:EA:7F:E7:B3:D6
         SHA256: 7A:F5:5D:0C:7C:CB:F0:91:D2:38:93:E4:9E:CE:01:73:20:4A:94:DD:95:0C:10:5F:B1:85:1C:DD:CC:7F:2D:47
         Signature algorithm name: SHA1withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  codeSigning
]

So everything seems the same, except the certificate fingerprints.

But I’ve actually been able to finally compile a new release with the same fingerprint, by logging into Windows from the hard drive of my old PC (I had tried that before but for some reason I couldn’t login before). I copied the project there, used the Flash Develop project file of an older version, and it creates the APK with the same certificate fingerprint as before.

And I am now virtually 100% sure that the certificate being used is the same. If I change the certificate path in project.xml, the certificate used changes accordingly. There is something that happens differently on my older system which causes the fingerprint to change, but I still haven’t figured out what it is. Although this solves the problem for now, it’s not a very good long-term solution :slight_smile:

Some answers on another thread said " …I used same key-store but different release key"

Perhaps there’s something to that, explaining the same validation dates, but different fingerprints?

But I’m always using the exact same keystore file, with only 1 certificate in it, which always has the same fingerprint. It’s when I build the project that the fingerprint gets changed in the APK (on my old system).