I know there are a lot of other people experiencing the INSTALL_PARSE_FAILED_NO_CERTIFICATES error when they forget to sign their apk. This is not the problem I'm describing. I will detail what I'm doing in several steps.
I have a zipaligned, signed apk file (AndroidWorld.apk). I can install this no problem. So far, so good.
Next, I decompile the apk with apktool. Also, so far so good.
After that, I use asmdex to modify the classes.dex file and inject some method logging. At this point, if I were to repackage the apk and attempt to install, it would definitely fail, since the signature of classes.dex no longer matches what's in the signing manifest. I realize that. So I repackage the apk, zipalign it, and then sign it with my own keystore:
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore "android_new_sample.keystore" -storepass mypass "C:\apk\AndroidWorld-release.apk" asample
Signing with keystore android_sample.keystore alias asample
adding: META-INF/MANIFEST.MF
adding: META-INF/ASAMPLE.SF
adding: META-INF/ASAMPLE.RSA
signing: assets/x.js
signing: assets/x.css
signing: assets/special_offers.html
signing: res/layout/displayjourneylist.xml
signing: res/layout/journey_row.xml
signing: res/layout/login.xml
signing: res/layout/searchjourney.xml
signing: res/layout/settings.xml
signing: res/layout/webview.xml
signing: res/layout/window_title.xml
signing: res/menu/option_menu.xml
signing: AndroidManifest.xml
signing: resources.arsc
signing: res/drawable-hdpi/header.png
signing: res/drawable-hdpi/ic_launcher.png
signing: res/drawable-ldpi/header.png
signing: res/drawable-ldpi/ic_launcher.png
signing: res/drawable-mdpi/header.png
signing: res/drawable-mdpi/ic_launcher.png
signing: classes.dex
signing: assets/x-runtime.properties
1 file(s) copied.
No complaints there, right? It looks like classes.dex has been signed and it didn't complain. But now, if I check the integrity of the signed apk with jarsigner -verify, it is not happy:
jarsigner.exe -verify -verbose -certs C:\apk\AndroidWorld-release-signed.apk
jarsigner: java.lang.SecurityException: invalid SHA1 signature file digest for classes.dex
I have made sure to uninstall the existing app on the device, but attempting to install this apk still gives me the INSTALL_PARSE_FAILED_NO_CERTIFICATES message. I have tried this with Java JDK 1.6 and 1.7, since I know there were some changes to jarsigner between those versions ( http://developer.android.com/tools/publishing/app-signing.html ). As you can see, I am specifying the sigalg and digestalg flags when signing.
Another weird quirk - if I use a debug keystore, all of this works fine.
Ok, after a bit of digging, here's what I found...
When instrumenting a previously signed application, but using a new keystore to sign it, there is a problem. Specifically, we end up with multiple signing manifests in \\meta-inf that all point to the same set of files. The app fails to install with the error INSTALL_PARSE_FAILED_NO_CERTIFICATES.
If you look at the signing manifest, you see two files:
Now, we modify classes.dex and sign the app with our own keystore:
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore android_new_sample.keystore AndroidWorld-release-final.apk asample
Enter Passphrase for keystore: mypass
updating: META-INF/ASAMPLE.SF
updating: META-INF/ASAMPLE.RSA
signing: assets/x.js
signing: assets/xx.css
signing: assets/special_offers.html
signing: res/layout/displayjourneylist.xml
signing: res/layout/journey_row.xml
signing: res/layout/login.xml
signing: res/layout/searchjourney.xml
signing: res/layout/settings.xml
signing: res/layout/webview.xml
signing: res/layout/window_title.xml
signing: res/menu/option_menu.xml
signing: AndroidManifest.xml
signing: resources.arsc
signing: res/drawable-hdpi/header.png
signing: res/drawable-hdpi/ic_launcher.png
signing: res/drawable-ldpi/header.png
signing: res/drawable-ldpi/ic_launcher.png
signing: res/drawable-mdpi/header.png
signing: res/drawable-mdpi/ic_launcher.png
signing: classes.dex
signing: assets/xxx.properties
No problems so far, we have all of the new signatures added to the manifest. However, attempting to verify the integrity of this apk now fails:
jarsigner.exe -verify -verbose -certs C:\apk\AndroidWorld-release-signed.apk
jarsigner: java.lang.SecurityException: invalid SHA1 signature file digest for classes.dex
The reason is that we now have duplicate signing information in \\meta-inf:
So classes.dex has 2 different signatures, one in Asample.sf, and one in Cert.sf:
Name: classes.dex (ASample.cf)
SHA1-Digest: mTf659/NTkTqqsAEZc3gTlbRpW8=
Name: classes.dex (Cert.sf)
SHA1-Digest: hkAsCEcLyM52Q6gq2uQIqc/7Gh8=
This causes verification and installation to fail. If I delete Cert.rsa and Cert.sf from the archive, it will verify and install. So the solution was to modify the zipfile and remove the original signing cert, leaving only my own.
我删除了文件CERT.SF / CERT.RSA / MANIFEST.MF,然后重新签名,一切顺利。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.