INSTALL_PARSE_FAILED_NO_CERTIFICATES 问题

INSTALL_PARSE_FAILED_NO_CERTIFICATES 问题

背景是我们自己搞了一套打渠道包的规则,最近更新到Gradle4.0.1之后,打包成功之后,在Android P的手机上安装出现问题,报错是:

adb: failed to install Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: 
Failed to collect certificates from /data/app/vmdl957487087.tmp/base.apk using 
APK Signature Scheme v2: Size of APK Signing Block is not a multiple of 4096: 8211]

其实原因已经说得很清晰了,就是APK Signing Block的大小要是4096的倍数。

所以简单的解决方法可以是,让增加的channel信息的长度固定为4096-12的大小


因为是基于原有的方案来做的,所以这里简单介绍下原来的方案。

《APK 签名方案 v2》位apk(zip)文件新增了一个APK Signing Block的区块,并在这个区块里面定义了一些内容,用于存储签名信息。

偏移      字节数            描述
@+0       8                这个Block的长度(本字段的长度不计算在内)
@+8       n                一组ID-value
@-24      8                这个Block的长度(和第一个字段一样值)
@-16      16               魔数 “APK Sig Block 42”

“APK 签名方案 v2 分块”存储在“APK 签名分块”内,ID 为 0x7109871a,其中包含signed data。
APK 签名方案 v2 负责保护第 1、3、4 部分的完整性,以及第 2 部分包含的“APK 签名方案 v2 分块”中的 signed data 分块的完整性。
因此,我们是可以按照规则,往APK Signing Block添加一些我们需要标记的内容的。
怎么加呢?

  1. 就是增加一组 size:ID:value 到原来的签名块中
  2. 修改原来签名块的长度
  3. 增加偏移,把原来的字节信息原样拷贝到新文件中

升级到gradle4.0之后,签名块增加了要4096对齐的规则。

PS:其实是搜到walle有相关的修改:

https://github.com/Meituan-Dianping/walle/commit/056359d8980828bc352f8d930733305547580c96

看到他的提交里面说是适配了 APK Signature Scheme v3

回到问题本身,4096对齐的规则 是通过增加一个 dummy ID-value 来实现的,简单来说就是加一个空的ID,把空间填满到4096的倍数。参考这个代码

https://android.googlesource.com/platform/tools/apksig/+/master/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java

// generateApkSigningBlock
// FORMAT:
// uint64:  size (excluding this field)
// repeated ID-value pairs:
//     uint64:           size (excluding this field)
//     uint32:           ID
//     (size - 4) bytes: value
// (extra dummy ID-value for padding to make block size a multiple of 4096 bytes)
// uint64:  size (same as the one above)
// uint128: magic

想了一下,这里的解决办法有两种。

  1. 参考walle的方法,手动去调节一下 extra dummy ID-value 的padding大小。
  2. 自己把channel信息补齐到4096的倍数。

最后我们是补得到4096的倍数,apk大小多4K,但是操作起来简单很多。

相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页