【问题标题】:INSTALL_PARSE_FAILED_NO_CERTIFICATES failure installing modified apk file (invalid SHA1 signature), even after signing with jarsignerINSTALL_PARSE_FAILED_NO_CERTIFICATES 安装修改后的 apk 文件失败(无效的 SHA1 签名),即使在使用 jarsigner 签名后也是如此
【发布时间】:2014-06-07 02:14:32
【问题描述】:

我知道有很多其他人在忘记签署他们的 apk 时遇到 INSTALL_PARSE_FAILED_NO_CERTIFICATES 错误。这不是我要描述的问题。我将分几个步骤详细说明我在做什么。

我有一个 zipaligned、签名的 apk 文件 (AndroidWorld.apk)。我可以安装这个没问题。到目前为止,一切顺利。

接下来,我使用 apktool 对 apk 进行反编译。此外,到目前为止一切顺利。

之后,我使用 asmdex 修改 classes.dex 文件并注入一些方法日志记录。此时,如果我要重新打包 apk 并尝试安装,它肯定会失败,因为 classes.dex 的签名不再匹配签名清单中的内容。我意识到这一点。所以我重新打包 apk,压缩对齐,然后用我自己的密钥库对其进行签名:

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 标志。

另一个奇怪的怪癖 - 如果我使用调试密钥库,所有这些都可以正常工作。

【问题讨论】:

    标签: java android jar-signing android-keystore


    【解决方案1】:

    好的,经过一番挖掘,这就是我发现的……

    检测以前签名的应用程序,但使用新的密钥库对其进行签名时,会出现问题。具体来说,我们最终会在 \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 有 2 个不同的签名,一个在 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,它将验证并安装。所以解决办法是修改zipfile,去掉原来的签名证书,只留下我自己的。

    【讨论】:

    • 我遇到了类似的问题。验证总是在 classes.dex 上阻塞,尽管我没有重复签名问题。在重建 jar 并辞职之前删除 META-INF 中的 Cert.* 并修复它。
    • 是的,最后。像往常一样,错误信息就像圣经一样解释。
    【解决方案2】:

    我已删除文件 CERT.SF/CERT.RSA/MANIFEST.MF,并重新签名,一切顺利。

    【讨论】:

    • 这对 4 年前给出的答案有什么补充?
    • 我需要,所以我想其他人也需要。
    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多