Search Unity

keystore generated on JDK 7 unable to read with JDK 8

Discussion in 'Android' started by andersemil, Mar 9, 2017.

  1. andersemil

    andersemil

    Joined:
    Feb 2, 2015
    Posts:
    112
    Just spent an entire day trying to work out why my old keystore used to sign our published Android app would not work on my new computer. Turns out that JDK 8 is unable to read it and only solution was to downgrade to JDK 7.

    Does anyone know of a way to regenerate or migrate the keystore certificate to a new JDK 8 compatible keystore? I suppose maybe exporting it to PKCS12 and back to JKS might work?

    Using the old file with JDK 8 gives me an error somewhere in "DerInputStream". So for now I will continue to use JDK 7.
     
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    I haven't encountered this issue myself. We have a very old keystore that was created with an earlier version of the JDK, but it still works now after we have upgraded to JDK 8.

    Can you post the full error message you're receiving ?
     
  3. andersemil

    andersemil

    Joined:
    Feb 2, 2015
    Posts:
    112
    Error: Unable to load certificates
    Error: Unable to initialize, java.io.IOException: DerInputStream.getLength(): Redundant length bytes found
     
  4. Grizzzly

    Grizzzly

    Joined:
    May 7, 2015
    Posts:
    9
    Just got the same error. Looks like it's jdk bug.
     
  5. Grizzzly

    Grizzzly

    Joined:
    May 7, 2015
    Posts:
    9
    Found that JDK version 8u112 does not have such error. Worked for me.
     
  6. andersemil

    andersemil

    Joined:
    Feb 2, 2015
    Posts:
    112
    I had to generate a new keystore and reimport both private key and certificate into it. Problem is, incredibly, you cannot do that with keytool! So I had to follow this guide, which I found after hours of searching!
     
  7. ESG-Steven

    ESG-Steven

    Joined:
    Mar 18, 2015
    Posts:
    38
    did you use the 1.6.0 jdk like he described?
     
  8. ESG-Steven

    ESG-Steven

    Joined:
    Mar 18, 2015
    Posts:
    38
    @andersemil

    Had you already uploaded your app to Google Play?
    If you haven't, you could have just generated a new keystore without any issue. We have uploaded already and that guide's end result is a completely different key than the one we originally had.
    If this worked for you, you've uploaded to Google Play before this, and you can still upload to Google Play (meaning same values), it'd be awesome to ask you what you did and how we diverged from that.

    Thanks
     
  9. kiwipxl

    kiwipxl

    Joined:
    Jun 9, 2015
    Posts:
    11
    Thanks for the link @andersemil
    I spent the day working on this issue. It turns out that our keystore might've been somewhat broken. Reading it in jdk 1.8_111 works fine but anything above jdk1.8_112 breaks. The weirdest part was that the sha1 of the keystore did not match the exported certificate from openssl. I tried exporting the cert of another keystore and the sha1 matched perfectly, so something was going on with our keystore.
    I didn't manage to fix it unfortunately though.

    However I figured out that manually signing our apk through apksigner or jarsigner with the same keystore produced the sha1 we wanted and not the exported certificate's sha1.
    It seems that gradle has a different signing process and used the certificates sha1 instead.

    So I'm not entirely sure what the issue actually was with our keystore, but I know that manually signing the apk works, so we're going to continue doing that from now on. Probably going to add a post process script to gradle to use apksigner instead of the standard gradle signing process.
     
  10. zippro

    zippro

    Joined:
    Dec 13, 2013
    Posts:
    7
    Still couldn't solved the issue. Is there anyone who knows the solution?
     
  11. andersemil

    andersemil

    Joined:
    Feb 2, 2015
    Posts:
    112
    There is no automatic solution afaik. If you change the keystore in anyway, the fingerpribt changes and google play store will not accept the apk.
    My solution is to use a temp keystore for the build process then open the apk and resign the whole damn thing using Jdk 7. I automated it on our own dev machines but ofcourse it will not work in cloud build.
     
    salranax likes this.
  12. Fatkid11

    Fatkid11

    Joined:
    Feb 1, 2018
    Posts:
    1
    Will Java update soon ? Is there any news from Java.
     
  13. salranax

    salranax

    Joined:
    Jan 4, 2017
    Posts:
    6
    Hello, I tried resigning the apk by following these steps: https://stackoverflow.com/questions/7119839/re-sign-an-android-apk
    But when i try to install the apk it says "there was a problem parsing the package"
    Can you explain how you resign and zipalign the apk?
    Thank You.

    Edit: I get "application failed to load" error now.
     
    Last edited: Apr 16, 2018
  14. salranax

    salranax

    Joined:
    Jan 4, 2017
    Posts:
    6
    Hello,
    i managed to solve the problem as following andersemil's method.
    Here is the solution:

    1- Use a temporary keystore to build an apk.

    2- On mac:
    use zip -d yourapp.apk "META-INF*"
    command on terminal to unsign the apk.
    On windows: change .apk to .zip and delete the META-INF folder and change .zip to .apk again.

    3- Sign the apk with java7's jarsigner
    jarsigner -verbose [B]-sigalg SHA1withRSA -digestalg SHA1[/B] -keystore AppKey.keystore android-release-unsigned.apk alliasName


    4- Then verify it with jarsigner
    jarsigner -verify android-release-unsigned.apk


    5- and lastly zipalign
    zipalign -v 4 android-release-unsigned.apk myTransporter-Final.apk

    and you are ready to publish it
     
  15. Pikuseru_

    Pikuseru_

    Joined:
    May 29, 2018
    Posts:
    1
    So I just had the same problem with an android app (not Unity) and a key and cert in a P12 - from what I could gather in my case was that the encoding of the signature in the certificate was incorrect in JDK 6 & 7. Specifically the encoding of the length of the signature as a “bit string”.

    OpenSSL corrected the encoding of the signature length but this changed the SHA1 fingerprint. JDK 8 just can’t read the certificate at all.

    My “solution” was to use JDK 7 to resign my APK so that the SHA1 stayed the same.

    Don’t know if that helps at all...

    https://stackoverflow.com/a/33499504

    https://lapo.it/asn1js/