androidapp签名详解
⼀、序
在将 App 发布到市场之前,很重要的⼀个步骤就是为 APK 进⾏签名,⼤部分时候,这个操作隐藏在了打包的流程中,⽽不被我们注意到。
签名的作⽤,除了证明 App 的所有权之外,还可以帮助 Android 市场和设备校验 APK 的正确性。
Android 的签名是⾃证明的,并不会对证书进⾏ CA 认证。也就是我们可以使⽤⼯具⾃⾏⽣成签名证书,只要是⼀个格式正确的签名,系统就会承认,并且允许安装。
⽣成签名的时,可以指定⼀个有效时间,这个时间默认为 25 年,并且 Google Play 也有硬性规定,上架的 App 签名有效期必须在
2033-10-22 ⽇期之后。所以只要不是⼿⽋修改了这个有效期,在当下这个时刻,是不会有问题,毕竟到现在还没有⼀款 App 存在 25年。
有些问题不在眼前,却是真实存在的。对于⼀款上架的 App,最重要的就是⽤户,⽽当签名失效之后,我们只能被迫替换签名,此时因为签名校验⽆法通过,就会导致旧⽤户⽆法覆盖安装。这些历史⽤户唯⼀的选择,就是卸载后重新安装。
好在这不仅仅是你我的问题,天塌下来有个⼦⾼的顶着,所以别担⼼,Google 已经着⼿在解决这个问题了。
⽅案就是 Android 9.0 新增的对 APK V3 签名的⽀持。
⼆、新的签名⽅案 V3
2.1 Android 的签名⽅案
Android 的签名⽅案,发展到现在,不是⼀蹴⽽就的。Android 现在已经⽀持三种应⽤签名⽅案:
V1 ⽅案:基于 JAR 签名。
V2 ⽅案:APK 签名⽅案 V2,在 Android 7.0 引⼊。
V3 ⽅案:APK 签名⽅案 V3,在 Android 9.0 引⼊。
V1 到 V2 是颠覆性的,为了解决 JAR 签名⽅案的安全性问题,⽽到了 V3 ⽅案,其实结构上并没有太⼤的调整,可以理解为 V2 签名⽅案的升级版,有⼀些资料也把它称之为 V2+ ⽅案。
因为这种签名⽅案的升级,本⾝就是向下兼容的,所以只要使⽤得当,这个过程对开发者是透明的。
V1 到 V2 ⽅案的升级,对开发者影响最⼤的,就是渠道签署的问题。在当下这个⼤环境下,我们想让不同渠道、市场的安装包有所区别,携带渠道的唯⼀标识,这就是我们俗称的渠道包。
好在各⼤⼚都开源了⾃⼰的签渠道⽅案,例如:Walle(美团)、VasDolly(腾讯)都是⾮常优秀的⽅案,想了解的可以先看看之前的⽂章:《Android 签名和多渠道打包原理》。
2.2 签名的历史
先从 Android 签名的历史讲起。
在上个世纪 80 年代,Phil Katz 创建了 ZIP 格式,可以将⽂件和⼀些元数组,组合在⼀个⽂件中,便于传输和存档,该格式是为了解决压缩、校验和冗余头等问题⽽提出的解决⽅案。
Sum 公司在上世纪 90 年代,将 ZIP 作为 JAR 格式的基础,⽽ JAR 本质上就是⼀个 ZIP 存档。在其中,META-INF ⽬录下会包含⼀些元数据和签名数据等信息。
Android 出现后,也沿⽤了 Java 的 JAR 的发布⽅式,将 APK 建⽴在 JAR 格式之上,在此基础上对 Dalvik 字节码 classes.dex 和资源resources.arsc 等⽂件添加更多标准化的结构。当时 Android 的 APK 完全依赖 JAR 的签名⽅案来确保应⽤程序的正确性,这就是我们俗称的 V1 ⽅案(JAR ⽅案)。
在 V1 签名⽅案中,并不会保护 APK 内的所有⽂件,会存在⼀些例外部分,即便被修改也不会导致签名失效,例如:ZIP 元数据。
同时,V1 ⽅案对 APK 内部被保护的原始⽂件,是单独进⾏计算数据摘要的,所以在验证时,需要先解压再验证,导致安装时会花费更多的时间,消耗更多的内存。
例如 V1 ⽅案中签渠道的⽅式就是利⽤了此特性,将渠道信息写⼊ META-INF ⽂件中,这不会破坏 V1 签名。
多年后,在 Android 7.0 中添加了⼀种新的签名⽅式,就是我们俗称的 V2 ⽅案。
V2 签名提供了更强⼤的 APK ⽂件验证,它不再检查包内单个⽂件,⽽是检查整个 APK。它在 ZIP ⽂
件中,插⼊⼀个额外的签名块,覆盖ZIP ⽂件中的其余部分。
在这个额外的签名块(Apk Signature Block V2)中,会对当前 APK 的其他部分签名。
从安全的⾓度 V2 会⽐ V1 更安全,V2 签名是验证整个打包后的 APK ⽂件,所以对其 APK ⽂件做“任何”改动都会破坏签名。注意这⾥的任何是带引号的,V2 签名的签名块其实是⼀个 K-V 的结构,可以向其中插⼊⼀些简单的数据⽽不破坏 V2 签名,这就是 V2 ⽅案下,多渠道的⽅案思路。
在引⼊ V2 ⽅案的同时,也保证了向后兼容,旧的 JAR 签名⽅案仍然在旧的设备(Android 7.0 以下)中⽣效,⽽在较新的设备上,也会判断是否使⽤ V2 签名,不是则依然会去校验 V1 签名。
V2 ⽅案解决了安全问题以及安装时验证的效率问题,但是它并没有解决前⾯提到的换签名问题。
2.3 Android 的 V3 ⽅案
Android 9.0 中引⼊了新的签名⽅式,它的格式⼤体和 V2 类似,在 V2 插⼊的签名块(Apk Signature Block V2)中,⼜添加了⼀个新快(Attr块)。
在这个新块中,会记录我们之前的签名信息以及新的签名信息,以密钥转轮的⽅案,来做签名的替换和升级。这意味着,只要旧签名证书在⼿,我们就可以通过它在新的 APK ⽂件中,更改签名。
V3 签名新增的新块(attr)存储了所有的签名信息,由更⼩的 Level 块,以链表的形式存储。
其中每个链表节点都包含⽤于为之前版本的应⽤签名的签名证书,最旧的签名证书对应根节点,系统会让每个节点中的证书,为列表中下⼀个证书签名,从⽽为每个新密钥提供证据来证明它应该像旧密钥⼀样可信。
这个过程有点类似 CA 证书的证明过程,已安装的 App 的旧签名,确保覆盖安装的 APK 的新签名正
确,将信任传递下去。
2.4 V3 签名的验证过程
Android 的签名⽅案,⽆论怎么升级,都是要确保向下兼容。
在引⼊ V3 ⽅案后,Android 9.0 及更⾼版本中,可以根据 APK 签名⽅案,V3 → V2 → V1 依次尝试验证 APK。⽽较旧的平台会忽略V3 签名并尝试 V2 签名,最后才去验证 V1 签名。
整个验证的过程,如下图:
需要注意的是,对于覆盖安装的情况,签名校验只⽀持升级,⽽不⽀持降级。也就是说设备上安装了⼀个使⽤ V1 签名的 Apk,可以使⽤V2 签名的 Apk 进⾏覆盖安装,反之则不允许。
三、总结时刻
Android 签名替换的问题,Google 已经在考虑了,9.0 新增的 V3 签名⽅案就是为了解决签名替换的。这些,肯定都是提前准备。
签名过期的问题,不需要太担⼼,我们只需要跟着 Google 的步伐就可以了。
最后⼩结⼀下结论,签名过期的问题,在 Android 9.0 上新⽀持的 V3 签名,已经有解决的⽅案了。
另外:
V1 签名遵循 JAR 的签名⽅式,单独验证 APK 压缩包中的⽂件。
V2 签名是针对 APK ⽂件的验证,将签名信息写⼊签名块中,增强了安全性和验证效率。
V3 签名在签名块中⼜增加了新块(attr),由更⼩的 level 块,以链表的形式存储多个证书。android获取真正的签名
在 V3 ⽅案中,最旧的证书为新块链表的根节点,以此对新证书签名,确保新证书正确有效。
V3 ⽅案还没有正式开放,在最新版的 Build Tools 版本 28.0.3 中的 Apksigner,尚不⽀持 V3 的 APK 签名⽅案。想尝鲜可以通过源代码⾃⾏编译。
从现有的资料来看,我⽐较关⼼的多渠道打包的⽀持⽅案,在升级到 V3 之后,旧的 V2 ⽀持的多渠道⽅案应该依然有效(或者少量改动)。
期待上线后的具体效果。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论