Android打包那些事

我们在完成一个项目后期肯定会进行打包操作,那么打包过程中的那些问题大家有了解过吗?今天就带大家了解一下Android打包的那些事.主要分四个部分:

Apk如何生成
Apk签名过程中遇到的问题
V1和V2签名的区别
美团两种打包方案的对比

Apk如何生成

首先先看一张图:
Apk编译流程
大致流程概述:
1、打包资源文件,生成R.java文件
2、处理aidl文件,生成相应java 文件
3、编译工程源代码,生成相应class 文件
4、转换所有class文件,生成classes.dex文件
5、打包生成apk
6、对apk文件进行签名
7、对签名后的apk文件进行对齐处理
这样一个Apk就会生成,因今天的重点不是Apk如何打包,所以大致过一下,想详细了解的同学可以自行百度哈.
我们再看一下Apk包的构成,将apk文件后缀改为.zip,然后解压……
Apk解压示意图
我们可以看到解压后的Apk有五个文件,那么这五个文件分别代表什么意思呢?
AndroidManifest:AndroidManifest.xml文件
Dex:dex文件
Res:资源文件
resources.arc:编译后的二进制文件
META-INF:签名文件
CERT.RSA保存了签名(私钥对.SF文件的加密数据)和公钥证书
CERT.SF.对MF文件的摘要信息以及.MF文件当中每个条目在用摘要算法计算
得到的摘要信息并用base64编码保存
MANIFEST.MF对每个文件的整体进行SHA1(hash)

注意META-INF这个文件,这将是我们今天的重点


Apk签名过程中遇到的问题

我们在平时的打包过程中肯定会看见下面这张图:
Apk打包签名
在我们打包的最后一个步骤,会询问我们签名类型,这个时候会有V1(Jar Signature)和V2(Full Apk Signature)两种类型供我们选择,那V1(Jar Signatur 以下均简称V1)和V2(Full Apk Signature 以下均简称V2)有什么区别呢?什么时候选择V1,什么时候选择V2呢?我们分析一下
做个小小的试验,在只勾选V1,只勾选V2,两个同时都勾选的情况下打包:
Apk安装试验

  • 只勾选v1,可以安装.

  • 勾选v1和v2可以安装

  • 只勾选v2,在7.0下安装会显示安装失败 安装包没有签名文件
    (上图为v2签名包在6.0上的安装提示)
    Android Studio 2.2 和Gradle 2.2.0插件会使用APK Signature Scheme v2和传统签名方案来签署应用。
    V2签名验证过
    V2签名过程
    在 Android 7.0 以上版本的设备上,APK 可以根据Full Apk Signature(v2 方案) 或者 JAR-signed( v1方案)进行验证;
    而对于7.0以下版本的设备其会忽略 v2 版本的签名,只验证 v1 签名
    寻找APK Signing Block,如果能够找到,则进行验证,验证成功则继续进行安装,如果失败了则终止安装
    如果未找到APK Signing Block,则执行原来的签名验证机制,也是验证成功则继续进行安装,
    如果失败了则终止安装.
    注:若v1,v2同时存在,走V2.
    原因:v1版本的META_INF的.SF文件属性当中有一个 X-Android-APK-Signed属性


V1和V2签名的区别

V1和V2是什么?有什么区别呢?
Android 支持两种应用签名方案,一种是基于 JAR 签名的方案Jar Signature(v1 方案),另一种是 Android Nougat (Android 7.0) 中引入的APK Signature Scheme V2方案。V1是JDK提供的针对jar包签名的通用工具,对apk中单个文件进行校验,签名后可进行修改,是对zip压缩包的每个文件进行验证,保护包中的文件,不保护包本身.(划重点)
V2:是Google官方提供的针对Android apk签名及验证的专用工具,位于androidsdk/build-tools/下,是压缩所有的字节工具,签名后无法再进行更改,安全,对zip压缩包的整个文件验证,签名验证时间更短(不需要解压验证),因而安装速度加快,zip包一个字节也不能改.
最核心的就一句话:V1是对单个文件进行验证,V2是对整个包进行验证

那么提出问题:为什么V2安装速度更快?验证时间更快?

  • 安全,验证整体二进制,不再可以修改压缩包里的文件

  • 速度,安装无需解压缩,缩短安装时间。


美团两种打包方案的对比

前面我们已经分析过V1签名和V2签名的区别,V1是对单个文件进行验证,V2是对整个包进行验证,那么针对这两种区别,我们分析下美团两种打包方案(这里只是分析打包的原理,具体打包的过程可以查看我给出的链接,或者百度搜索美团打包方案):

  • 修改Apk包内容,具体如何打包请参考:美团第一种打包方案
    原理:在解压的Apk文件中,我们可以看见META-INF文件夹,在META-INF中写入空文件作为渠道号,不需要重新签名,该目录不参与签名校验
    打包脚本: python package.py app-release.apk channellist

在META-INF目录下的三个文件,就是一个Android应用程序包被正确签名之后的生成文件,当这个程序包中的文件被修改以后,验证信息就需要重新生成,否则验证的签名信息就不正确,我们可以放入了一个空文件,利用文件名来表示渠道方式的完成。如果放入了一个非空的文件,这时签名验证的机制就会被破坏.我们在该文件下新建一个空文件,然后以文件名为我们渠道号的名称,在打包过程中读取文件名作为渠道标识.
这是第一种方案,优点快,十几个包顶多十几秒,缺点:在7.0上就失效,不支持V2
写入360的空文件

  • 第二种打包方式Walle打包
    了解Walle打包原理前先了解下Zip压缩文件的简介
    ZIP文件格式:
    [local file header + file data + data descriptor]{1,n} + central directory + end of central directory record
    [文件头+文件数据+数据描述符]{此处可重复n次}(压缩的所有文件的内容信息)+核心目录(压缩文件的目录信息)+目录结束标识
    (标记压缩的目录数据的结束)
    Zip文件格式分析
    zip文件格式
    原理:APK 被分为 4 部分:
    Contents of ZIP entries (从文件头开始直到APK Signing Bloc)
    APK Signing Block(签名,摘要,签名算法,证书链等信息)
    ZIP Central Directory
    ZIP End of Central Directory
    1、3、4的内容受到APK Signing Block 保护,准确的说是受APK Signing Bloc中的签名信息保护,Signing Block 字节数 (不含自身计数) (uint64)
    “ID-value” 对序列:
  • 此“ID-value” 长度 (uint64)
  • ID (uint32)
  • value (可变长度: “ID-value” 长度 - 4个字节)
  • Signing Block 字节数 (与前面的数值相同) (uint64)
  • magic“APK Sig Block 42” (16 个字节)
    为向后兼容考虑,ID-value对设计成了可以存在多个。
    V2 签名是数据块中的一个ID-value对,其ID为 0x7109871a,值即为“签名信息”(signed data)。在验证 V2 签名过程中,会跳过验证器不认识的 ID。(重点)

应用安装时如何校验呢?

public static ByteBuffer findApkSignatureSchemeV2Block(
            ByteBuffer apkSigningBlock,Result result) {
            int id = pairs.getInt();
            if (id == APK_SIGNATURE_SCHEME_V2_BLOCK_ID) {
                return getByteBuffer(pairs, len - 4);}}}

那么我们可以提供一个自定义的ID-value并写入该区域,从而为快速生成渠道包服务
so,Waller干了什么事:

  • 对新的应用签名方案生成的APK包中的ID-value进行扩展,提供自定义ID-value(渠道信息),并保存
    在APK中
  • APK在安装过程中进行的签名校验,是忽略我们添加的这个ID-value的,这样就能正常安装了
  • 在App运行阶段,可以通过ZIP的EOCD(End of central directory)、Central directory等结构中的信息,找到我们自己添加的ID-value,从而实现获取渠道信息的功能
    因为APK包的区块1、3、4都是受保护的,任何修改在签名后对它们的修改,都会在安装过程中被签名校验检测失败,而区块2(APK Signing Block)是不受签名校验规则保护的.
    APK 签名方案 v2 负责保护第 1、3、4 部分的完整性,以及第 2 部分包含的“APK 签名方案 v2 分块”中的 signed data分块的完整性。

打包流程演示: 1、写入单个渠道
java -jar walle-cli-all.jar put -c yingyongbao app.apk
2、写入多个渠道
java -jar walle-cli-all.jar batch -c yingyongbao,360,xiaomi app.apk
3、通过指定渠道配置文件
首先在同级目录下新建一个channel.txt文件然后写入渠道信息:
java -jar walle-cli-all.jar batch -f channel app.apk
美团链接:

总结:

  • Android签名分为V1和V2两种,若只选择V1,则肯定可行,但是包存在风险,若只选择V2,则7.0下不可使用.尽量同时使用V1和V2签名.
  • V1是对APk包中单个文件进行验证,V2是对整个包进行验证
  • 美团两种方案也是基于这两种签名的区别上做的变动

    over—-

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值