- 1.将aidl文件使用aidl工具转换为编译器能够识别编译的java文件
- 2.将资源文件(AndroidManifest.xml,xml布局文件,资源resources文件,asserts下的资源文件)使用aapt工具(最近几个版本已经改为优化后的aapt2)一部分打包为编译后的资源文件(resources.arsc),并生成对应的R文件,以及生成Proguad 配置文件
- 3.将java源文件以及aidl生成的java文件还有R文件,android类库文件使用javac一起编译为class文件
- 4.使用proguard对class文件和资源文件进行混淆和优化。
- 5.然后和第三方类库class文件一起打包生成Android虚拟机可以识别的Dalvik Byte Code类型的dex文件
- 6.使用apkBuilder工具,将dex文件和资源文件以及so库打包生成未签名的apk文件
- 7.使用jarSigner工具将apk文件使用keystore签名生成签名后的apk文件
- 8.使用zipAlign对apk进行对齐处理,对齐的过程就是将 APK 文件中所有的资源文件距离文件的起始位置都偏移4字节的整数倍,这样通过 mmap 访问 APK 文件的速度会更快,并且会减少其在设备上运行时的内存占用
到此我们已经了解另外apk的打包和编译的一个完整流程
这里我们提出两个问题
- 1.为什么要将xml文件编译为resources.arsc中的二进制流格式?
- 2.app运行的时候,系统是如何找到对应的资源文件的?
这两个问题其实答案都是相通的。
在前面一篇文章讲解class文件结构的时候,说到过,class文件有一个常量池的结构,其存储了当前class文件所需的所有常量字符串,外部访问常量的时候,是通过索引的方式进行访问
这里xml文件编译为resources.arsc过程也是这么一个方式。
那为什么要这么使用呢?
字符串复用,资源复用:当前xml文件的标签,属性名称以及属性值都会被编译到resources.arsc资源池中,且去除重复的字段,外部访问的时候,只需要访问使用当前资源索引就可以在资源池中找到对应的资源信息,且不需要每次都去解析对应的字符串,解析资源效率高。第二个问题在第一个问题解中就可以找到了
前面都是讲解源文件编译过程,这里我们再来突出下apk的签名校验过程
APK签名密钥算法:1.消息摘要如MD5加密后的字符串就是一个消息摘要特点:可以保证数据完整性,但是无法保证数据安全性和不可篡改性
2.数字签名两部分组成:签名算法和验证算法
知识点:
公钥密码体制 对称加密算法和非对称加密算法
- 1.公钥密码体制 :分为公钥和私钥和加密解密算法:常见为RSA算法
加密:通过公钥使用加密算法对明文进行加密,得到密文
解密:通过私钥使用解密算法对密文进行解密,得到明文
公钥加密的内容一定需要知道私钥才能解出明文由管理员生成一套公钥和私钥。公钥和算法是公开的,私钥是只有管理员才有,保证数据不可以篡改
- 2.对称加密算法:常见有DES 3DES AES等,对称加密算法使用同一个密钥对明文进行加解密操作,所以需要保证密钥的安全性。
- 3.非对称加密算法:常见有RSA算法加密使用的密钥和解密使用的密钥是不相同的。
RSA:
- 1.加密:终端使用公钥加密,服务端使用私钥解密:数据只能由服务端解密,可以保证不可篡改性。
- 2.签名:服务端使用私钥加密,终端使用公钥解密:可以保证数据是由服务端使用私钥加密后的数据,且服务端不能否认这个结果
- 数字签名简介:非对称加密技术 消息摘要技术的结合
如果单独使用私钥进行加密只可以保证数据的完整性,无法保证数据的保密性且数据大时加密的效率速度很低,所以采用加密摘要算法生成的摘要消息弥补缺点
具体步骤:
发送者:
- 1.发送者使用使用MD5获得摘要
- 2.发送者使用私钥对摘要加密获得数字签名
- 3.发送者需要将原始信息和数字签名一同发送给接收者
接收者:
- 4.接收者先把接收到的原始消息用同样的摘要算法摘要,形成“准签体”。
- 5.对附加上的那段数字签名,使用预先得到的公钥解密。
- 6.比较前两步所得到的两段消息是否一致: 如果一致,则表明消息确实是期望的发送者发的,且内容没有被篡改过; 相反,如果不一致,则表明传送的过程中一定出了问题,消息不可信。
签名过程:
签名三兄弟:1.MANIFEST.MF2.CERT.SF3.CERT.RSA
- 1.MANIFEST.MF
该内容保存的是逐一遍历 APK 中的所有条目,使用摘要算法如SHA1或者SHA256算出摘要信息,并使用base64编码后,存放到MANIFEST.MF块中每个块包含一个Name属性:存放该文件的路径
- 2.CERT.SF
SHA1-Digest-Manifest:对整个 MANIFEST.MF 文件做 SHA1(或者 SHA256)后再用 Base64 编码
SHA1-Digest:对 MANIFEST.MF 的各个条目做 SHA1(或者 SHA256)后再用 Base64 编码
- 3.CERT.RSA
这里会把之前生成的 CERT.SF 文件,用私钥计算出签名, 然后将签名以及包含公钥信息的数字证书一同写入 CERT.RSA 中保存
这个数字证书就是我们android签名的时候使用的签名keystore文件:
使用下面命令查看签名证书情况:
penssl pkcs7 -inform DER -in /<文件存放路径>/Sample-release_new/original/META-INF/CERT.RSA -text -noout -print_certs
完整签名流程: