Sign Android Native apk with Adobe Air certificate
Asked Answered
E

3

2

I need help with signing Android Native app with existing .p12 certificate generated for Adobe Air. Application was done in Adobe Air few years ago, signed and published to Google play. Now when moving from Adobe Air to Android Native, in order to upgrade app to the new version on store, it needs to be signed with the same private key. The problem is that it is not possible to open/read the key via keytool on newer versions of java. Trying to read the .p12 certificate will return:

java.security.cert.CertificateException: Unable to initialize, java.io.IOException: DerInputStream.getLength(): Redundant length bytes found

or

keytool error: java.io.IOException: Invalid keystore format

depending on a command I'm trying to execute.

(1) Asking old friend Google didn't bring much, but more frustration. I did like it was suggested in jira ticket of openjdk, i tried to use OpenSSL to fix redundant bytes in this way:

openssl pkcs12 -in pkcs12-file -out key-and-cert -nodes -passin pass:abcXYZ 
openssl pkcs12 -in key-and-cert -export -out new-pkcs12-file -passout pass:abcXYZ

This commands will execute successfully, BUT, the generated SHA1 key (...:F7) will not be the same as original one (...:E5)! That actually is not a surprise, since changing any part of the file(like removing redundant bytes) will end in different SHA key. Ok, so obviously this is not a solution.

(2) Next thing I tried, was to extract private key and certs as plain text(.pem) files from my original .p12 certificate, in order to try to create a new .jks file. So I managed to extract my private key, and my certs from original .p12 certificate into plain text. Then using keytools and openssl I tried to create my new .jks file with original data as mentioned here: How to Creat JKS KeyStore file from existing private key and certificate Well, it worked in a way that my new .jks file was created, BUT the SHA1 key (again ...:F7) was not the same as the original one (...:E5).

(3) My next step was reading and looking a much more over the internet. Found some solutions that are suggesting that conversion was last working in java 1.8.0_111, and every distribution of java above that had the same problem. So, let's install java 1.8.0_111 and give it a shot. Sure, it didn't worked. The problem stayed the same. Also tried in java 1.10, and Oracle versions, still not working

(4) Last thing I did, I installed java 1.6 and tried with it, and there was no problem, it worked perfectly, i managed to read the .p12 with no problem, convert it to .jks with no problems at all, worked like a charm. Generated SHA1 key (...:E5) was the same as the original one (...:E5)!!!

BUT, the problem is that application I need to sign with that certificate is developed with java 1.8, and java 1.8 can't read that certificate. So I'm quite frustrated at this point, since it's already couple of days I'm losing on this problem.

So, can't read it, can't regenerate it, can't sign the app ...

So my question is: is it possible, and if it is, how to sign Android apk with .p12 certificate?

I'm not sure how common this problem is, but any possible help is more then welcome.

Edenedens answered 9/7, 2018 at 17:21 Comment(0)
E
1

I finally did manage to find the best solution to this problem that I was facing. And actually the solution was right in front of me, with a little bit of effort.

I tried switching to java 1.6 version just to sign the app, and actually I did manage to do the signing. Afterwords i would transfer the app again to 1.8 java environment and did the zipalign, successfully! When I managed all of this, i was really happy, hoping Google Play will finally accept the apk. My hope died as soon as I uploaded the apk to the store. Google Play said that not all the files were signed and that I need to upload apk with all files signed. Can you imagine the level of frustration?

My problem was i had old .p12 certificate that was not possible to read in AndroidStudio or to convert to jks, but I was able to extract my private key, and my certificate from that file.

After I tried to look around a bit more, I managed to find the solution with apksigner tool.

Actually what i did was, I built an .apk signed with debug key, and after that just used apksigner tool, provided with my private key and certificate file, and finally the apk was signed. Then I was able to upload the apk to the Google Play Store with no problems.

The command that I used to sign the apk with apksigner tool is:

./apksigner sign --key <your_private_key_in_.pcks8> --cert <your_certificate_in.der> <your_debug_signed_application_in.apk>

Here it is necessary to notice that your key has to be in .pcks8 format, otherwise the command wont work. Also apksigner was run as script on linux, thats why "./" before apksigner. If you have this tool on windows or installed on some other way, you should be good to start command just with apksigner.exe or apksigner.

If you have your key in plain text (.pem) format, transfering it to the .pcks8 format can be done with openssl command:

openssl pkcs8 -topk8 -inform PEM -outform DER -in <your_private_key_in.pem> -out <your_private_key_in.pcks8> -nocrypt
Edenedens answered 12/7, 2018 at 9:22 Comment(0)
A
0

Hate to be the bearer of bad news, but this is one of the reasons why version control is paramount in enterprise environments. When things update, builds can break.

There are three things I thought of which I didn't see listed above:

1] If you are using an IDE like Android Studio or IntelliJ, you could try breaking your project down into Java 1.8 code and Java 1.6 code. For example, you could create a keystore-signing module, and then add gradle commands for it to build using Java 1.6, while the rest of your project modules build using Java 1.8.

2] You could try creating your own signing class, and make direct calls to Java 1.6 classes which you could add manually to your project.

3] You could use a new keystore, change your package name, and point your former store listing to your new Java 1.8 app. This is probably the least preferable as it would be considered a new app on the store.

Albedo answered 9/7, 2018 at 19:53 Comment(2)
Your first suggestion is something i didn't think of, thank you. I will try that and few more things and if I succeed I will write an answer how I did it.Edenedens
I wrote the solution that worked for me, you can check it out. Thank you for your ideas ;)Edenedens
B
0

We could not sign our apps with legit certificates. So instead we published using a self-made certificate to compile / publish the app. Then we used Microsoft's Signtool(.exe) to do the job. Worked like a charm.

Blastema answered 21/8, 2018 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.