我知道有很多其他人在忘记签名他们的apk时遇到INSTALL_PARSE_FAILED_NO_CERTIFICATES错误。这不是我所描述的问题。我将详细说明我在几个步骤中所做的事情。
我有一个zipaligned,签名的apk文件(AndroidWorld.apk)。我可以安装这个没问题。到目前为止,非常好。
接下来,我用apktool反编译apk。此外,到目前为止一切顺利。
之后,我使用asmdex修改classes.dex文件并注入一些方法记录。此时,如果我要重新打包apk并尝试安装,那肯定会失败,因为classes.dex的签名不再符合签名清单中的内容。我意识到了。所以我重新打包apk,zipalign它,然后用我自己的密钥库签名:
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.
没有抱怨,对吗?它似乎已经签署了classes.dex并且它没有抱怨。但是现在,如果我用jarsigner -verify检查签名apk的完整性,那就不开心了:
jarsigner.exe -verify -verbose -certs C:\apk\AndroidWorld-release-signed.apk
jarsigner: java.lang.SecurityException: invalid SHA1 signature file digest for classes.dex
我已确保卸载设备上的现有应用,但尝试安装此apk仍然会向我提供INSTALL_PARSE_FAILED_NO_CERTIFICATES消息。我已经尝试过使用Java JDK 1.6和1.7,因为我知道这些版本之间的jarsigner有一些变化(http://developer.android.com/tools/publishing/app-signing.html)。如您所见,我在签名时指定了sigalg和digestalg标志。
另一个奇怪的怪癖 - 如果我使用调试密钥库,所有这一切都可以。
答案 0 :(得分:5)
好的,经过一番挖掘,这就是我发现的......
在检测以前签名的应用程序时,但使用新的密钥库对其进行签名时,会出现问题。具体来说,我们最终在\ meta-inf中有多个签名清单,这些清单都指向同一组文件。该应用无法安装错误INSTALL_PARSE_FAILED_NO_CERTIFICATES。
如果查看签名清单,您会看到两个文件:
现在,我们修改classes.dex并使用我们自己的密钥库对应用程序进行签名:
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
到目前为止没有问题,我们已将所有新签名添加到清单中。但是,尝试验证此apk的完整性现在失败了:
jarsigner.exe -verify -verbose -certs C:\apk\AndroidWorld-release-signed.apk
jarsigner: java.lang.SecurityException: invalid SHA1 signature file digest for classes.dex
原因是我们现在在\ meta-inf中有重复的签名信息:
所以classes.dex有两个不同的签名,一个在Asample.sf中,另一个在Cert.sf中:
Name: classes.dex (ASample.cf)
SHA1-Digest: mTf659/NTkTqqsAEZc3gTlbRpW8=
Name: classes.dex (Cert.sf)
SHA1-Digest: hkAsCEcLyM52Q6gq2uQIqc/7Gh8=
这会导致验证和安装失败。如果我从存档中删除Cert.rsa和Cert.sf,它将验证并安装。因此,解决方案是修改zip文件并删除原始签名证书,只留下我自己的。
答案 1 :(得分:-1)
我已删除文件CERT.SF / CERT.RSA / MANIFEST.MF,然后重新签名,一切顺利。