android study 9 signature

Author Avatar
Xzhah 7月 03, 2022
  • 在其它设备中阅读本文章

android签名机制

1.初识android程序签名

​ 在android系统中,所有安装到系统的应用必须有一个数字证书。这个数字证书用于标志程序作者,以及在应用程序之间建立信任关系。

签名的作用

​ 1) 签名可以证明apk的所有者,通过对Apk进行签名,开发者可以证明自己对apk的所有权与控制权。签名可用于程序的安装和更新,软件包管理器会同构签名证书和数字摘要来验证程序是否被篡改。

​ 2) 有利于程序升级。当旧版本与新版本的数字证书相同时,android系统会认为这两个程序是同一个程序的不同版本。如果证书不同,系统则认为是两个不同的程序,会要求新程序更改包名。

​ 3) 有利于程序的模块化设计,android系统允许拥有同一签名的程序运行在同一进程中,所以开发者可以分模块开发,用户只需要在需要的时候下载合适的模块即可。

​ 4) 通过permission的方式在多个程序间共享数据和代码。如果某个权限(permission)的protectionLevel是signature,则这个权限就只能授予那些跟该权限所在的包拥有同一个数字证书的程序。

2.签名的验证方式

​ 发送者对文件计算摘要,然后用私钥签名。把密文,证书,公钥发送给接收端。接收端使用证书认证身份,然后用公钥解密,自己计算一遍摘要,对比摘要是否相同确保完整性。

2.1 v1签名

​ v1是基于jar签名,jarsigner

​ 首先META-INF目录下有3个和签名有关的文件

​ 1)MANIFEST.MF:APK所有原始文件的数据摘要的base64编码,数据摘要算法一般就是SHA1或者SHA256。

​ 2)CERT.SF: 首先计算MANIFEST.MF文件的数据摘要。然后base64编码记录在CERT.SF的文件头里。逐条计算MANIFEST.MF文件中每一个块的数据摘要,并经过BASE64编码后,记录在CERT.SF中的同名块中,属性的名字是“SHA1-Digest

​ 3)CERT.RSA:把之前生成的CERT.SF文件用私钥计算出签名,然后将签名以及含公钥信息的数字证书一同写入CERT.RSA文件。

​ 所以生成签名的过程就是:

​ 1) 对APK内部所有文件,提取摘要后base64编码,生成指纹清单MANIFEST.MF

​ 2) 对指纹清单的数据计算摘要,然后base64编码保存到CERT.SF文件主属性中,计算指纹清单文件内每一个数据块的数据摘要,编码后保存到CERT.SF的文件属性中

​ 3)计算CERT.SF文件摘要,然后签名,最后把签名和证书一同保存到CERT.RSA文件中

v1签名的缺陷

​ v1签名方案是不会保护到APK内所有内容的,并且验证时候不够迅速,需要先解压然后验证每个文件的摘要。因此就引入了v2方案

2.2 v2签名

​ v2签名是对APK本身进行摘要计算,那么则不需要解压APK的操作,减少了校验时间。并且针对整个APK的摘要计算,修改apk中任意一个文件都会不通过校验。

apk文件格式

​ apk文件本质上是一个ZIP压缩包,而ZIP格式是固定的,主要由三部分构成:

​ 1)内容块: 所有压缩文件都在这里面,每个压缩文件有一个local file header,主要会记录文件名,压缩算法,压缩前后大小,修改时间,CRC32值等。

​ 2)中央目录:包含了多个central directory file header,和每个local file header一一对应。每个中央目录文件头主要记录了压缩算法,注释信息,local file header的偏移等。

​ 3)最后是EOCD(end of central record),主要记录了中央目录大小和偏移,注释信息等。

​ v1只会校验内容块中的压缩文件。

​ v2会在apk中新增一个签名块,新的块中存了签名,摘要,签名算法,证书链等信息。APK签名块位于中央目录之前,文件数据之后。V2签名同时修改了EOCD中的中央目录的偏移,使得签名后的APK还符合ZIP结构。

​ v2方案会把APK分块签名,分成1M的块,计算每个块的摘要,以及针对所有摘要计算一个总摘要。再对总摘要进行签名。每个块的摘要,证书链,额外信息会类似一个MANIFEST.MF文件,然后计算这个文件的数字签名,形成类似SF文件,最后把“MF”和”SF”文件与公钥通过keystore签名后,形成签名块放入apk文件中。

2.3 v3签名

​ v2签名的问题在哪里呢?签名是默认25年有效期的,如果在签名过期或者密钥泄露想更换签名的情况下,不是那么方便,而v3在v2的基础上支持了密钥轮转。

​ 具体来说,即v3可以在签名部分添加新的证书,在这个新块中,会记录之前的签名信息以及新的签名信息,以密钥转轮的方案,来做签名的替换和升级。这意味着,只要旧签名证书在手,开发者就可以通过它在新的 APK 文件中,更改签名。v3 签名新增的新块(attr)存储了所有的签名信息,由更小的 Level 块,以链表的形式存储。

​ 其中每个节点都包含用于为之前版本的应用签名的签名证书,最旧的签名证书对应根节点,系统会让每个节点中的证书为列表中下一个证书签名,从而为每个新密钥提供证据来证明它应该像旧密钥一样可信。

References

https://www.jianshu.com/p/145fb9ad6f07