一、打包过程
- 打包流程:
-
aapt阶段:
- 使用aapt来打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样)
-
aidl阶段
- AIDL (Android Interface Definition Language), Android接口定义语言,Android提供的IPC (Inter Process Communication,进程间通信)的一种独特实现。这个阶段处理.aidl文件,生成对应的Java接口文件
-
Java Compiler阶段
- 通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件
-
dex 阶段
- 通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex
-
apkbuilder阶段
-
将classes.dex、resources.arsc、res文件夹(res/raw资源被原装不动地打包进APK之外,其它的资源都会被编译或者处理)、Other Resources(assets文件夹)、AndroidManifest.xml打包成apk文件
res/raw和assets的相同点:两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制
res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类
-
-
Jarsigner阶段
- 对apk进行签名,可以进行Debug和Release 签名
-
通过zipalign工具,将签名后的apk进行对齐处理
二、签名过程
-
签名是什么
作用:①确保消息来源的真实性 ②确保消息不会被第三方篡改
在 APK 中写入一个「指纹」。指纹写入以后,APK 中有任何修改,都会导致这个指纹无效,Android 系统在安装 APK 进行签名校验时就会不通过,从而保证了安全性
-
如何实现签名
-
消息摘要
消息数据上,执行一个单向的 Hash 函数,生成一个固定长度的Hash值,这个Hash值即是消息摘要
消息摘要只能保证消息的完整性,并不能保证消息的不可篡改性
-
数字签名
一个完整的数字签名方案应该由两部分组成:签名算法和验证算法
RSA 密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的
数字证书
-
-
Android中的签名方案
-
V1:基于Jar签名
MANIFEST.MF : 逐一遍历 APK 中的所有条目,如果是目录就跳过,如果是一个文件,就用 SHA1(或者 SHA256)消息摘要算法提取出该文件的摘要然后进行 BASE64 编码
CERT.SF : 对MANIFEST.MF 进行进一步摘要
CERT.RSA : 会把之前生成的 CERT.SF 文件,用私钥计算出签名, 然后将签名以及包含公钥信息的数字证书一同写入 CERT.RSA 中保存
-
签名过程
-
校验过程
-
签名校验速度慢
- 校验过程中需要对apk中所有文件进行摘要计算,在 APK 资源很多、性能较差的机器上签名校验会花费较长时间,导致安装速度慢
-
完整性保障不够
- META-INF 目录用来存放签名,自然此目录本身是不计入签名校验过程的,可以随意在这个目录中添加文件,比如一些快速批量打包方案就选择在这个目录中添加渠道文件
-
V2:Android7.0引入
全文件签名方案,能发现对Apk的受保护部分进行的所有更改,从而有助于加快验证速度并增强完整性保证
v2 签名模式在原先 APK 块中增加了一个新的块(签名块),新的块存储了签名,摘要,签名算法,证书链,额外属性等信息
就是把 APK 按照 1M 大小分割,分别计算这些分段的摘要,最后把这些分段的摘要在进行计算得到最终的摘要也就是 APK 的摘要。然后将 APK 的摘要 + 数字证书 + 其他属性生成签名数据写入到 APK Signing Block 区块
-
签名过程:
-
校验流程:
-
V3:Android9.0引入
它的格式大体和 v2 类似,在 v2 插入的签名块(Apk Signature Block v2)中,又添加了一个新快(Attr块)
-
校验过程
-