• 面试:Android 签名校验机制 v1、v2、v3


    探究 Android 签名机制和原理 - 腾讯云开发者社区-腾讯云

    一、APK签名可以带来以下好处

    • 应用程序升级 如果想无缝升级一个应用,Android系统要求应用程序的新版本与老版本具有相同的签名与包名。若包名相同而签名不同,系统会拒绝安装新版应用。
    • 应用程序模块化 Android系统可以允许同一个证书签名的多个应用程序在一个进程里运行,系统实际把他们作为一个单个的应用程序。此时就可以把我们的应用程序以模块的方式进行部署,而用户可以独立的升级其中的一个模块。
    • 代码或数据共享 Android提供了基于签名的权限机制,一个应用程序可以为另一个以相同证书签名的应用程序公开自己的功能与数据,同时其它具有不同签名的应用程序不可访问相应的功能与数据。
    • 应用程序的可认定性 签名信息中包含有开发者信息,在一定程度上可以防止应用被伪造。例如网易云加密对Android APK加壳保护中使用的“校验签名(防二次打包)”功能就是利用了这一点。

    二、签名的目的

    1. 对发送者的身份认证:由于开发商可能通过使用相同的package name来混淆替换已经安装的程序,以此保证签名不同的包不被替换。

    2. 保证信息传输的完成性:签名对于包中的每个文件进行处理,以此确保包中内容不被替换。

    3. 防止交易中的抵赖发生,market对软件的要求。

    三、签名原理

    简单来说总体分为以下几个步骤:

    1. MANIFEST.MF:一级摘要文件,对Apk中的每个文件做一次算法(数据摘要+Base64编码),保存到MAINFEST.MF

    2. CERT.SF二级摘要文件:对MAINFEST.MF整个文件做一次算法(数据摘要+Base64编码),存放到CERT.SF文件的头属性中,在对MAINFEST.MF文件中各个属性块做一次算法(数据摘要+Base64编码),存放到一个属性块中。

    3. CERT.RSA 签名文件:对CERT.SF文件做签名,内容存档到CERT.RSA中。最重要,里面保存了公钥、所采用的加密算法 和CERT.SF中的内容的用私钥进行加密之后的值(签名)

    其中包含了公钥、加密算法等信息。首先,对前一步生成的 CERT.SF 使用了 SHA256(SHA1)生成了数字摘要并使用了 RSA 加密,接着,利用了开发者私钥进行签名。然后,在安装时使用公钥解密。最后,将其与未加密的摘要信息(MANIFEST.MF文件)进行对比,如果相符,则表明内容没有被修改。

    这一步中,即使开发者修改了程序内容,并生成了新的摘要文件,MANIFEST.MF能与内容对应起来,CERT.SF也能与内容对应起来,但是攻击者没有开发者的私钥,所以不能生成正确的签名文件(CERT.RSA)。

    签名和验证的过程可以用下图表示

    apk签名验证和数字签名原理 - 简书

    通过非对称加密和解密:

    加密过程:使用开发者的私钥对摘要信息进行签名

    解密过程:使用公钥解密,拿着解密后的值和摘要信息对比,一致则通过校验安装成功,否则安装失败。

    那有人会问,我把CERT.RSA中也修改了,把公钥和签名都替换了,重新生成一个CERT.RSA不就行了么?

    这就涉及到另一个概念:数字证书。

    前面提到CERT.RSA 为签名和数字证书(公钥和辅助的身份信息)组成。

    • 签名就是用私钥对摘要信息加密后的密文。
    • 数字证书是开发者身份的信息,其中最主要的是公钥,其次还有辅助身份信息。比如所有者,签发人,有效期等。

    公钥代表了开发者主体身份的唯一性。公钥一样,开发者主体就是一个,公钥不一致肯定是不同的开发主体。

    以微信为例,假设你手机上安装过微信,并且你修改微信apk中的个CERT.RSA,替换成了你自己的公钥,和你自己私钥加密后的签名。安装的时候,Android系统检测到,同一个包名,新apk的公钥和已安装的不一致,那么系统就会认为开发者主体不一致,要安装新的apk,需要先把就的apk卸载掉(系统认为公钥不一致,是两个不同的apk,但是两个不同的apk,包名不能一致,需要卸载其中一个)

    如果手机上原先没有安装过微信,此时安装修改了签名文件的apk,Android系统是可以校验通过,允许安装的。

    那有同学又问了,数字证书中的辅助身份信息,如所有者,签发人,有效期等,这些辅助身份信息和公钥怎样建立一个可信任的匹配关系呢?毕竟我可以伪造数字证书,保留原有的辅助身份信息,用我自己的公钥替换掉原有的公钥信息,神不知鬼不觉。

    数字证书的认证,这就涉及到数字证书结构和CA认证机构了。 

    四、签名方案

    Android 支持以下三种应用签名方案:

    • v1:基于 JAR 签名,jarsigner 或者 apksigner
    • v2:APK 签名方案 v2(在 Android 7.0 引入)
    • v3:APK 签名方案 v3(在 Android 9 引入)

    v1签名过程:

    v1校验过程:

    v1 签名有两个地方可以改进:

    https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/Framework/Android%20%E7%AD%BE%E5%90%8D%E6%A0%A1%E9%AA%8C%E6%9C%BA%E5%88%B6.md

    Android v1、v2、v3签名详解 - 知乎

    签名校验速度慢 校验过程中需要对apk中所有文件进行摘要计算,在 APK 资源很多、性能较差的机器上签名校验会花费较长时间,导致安装速度慢。

    - 完整性保障不够 META-INF 目录用来存放签名,自然此目录本身是不计入签名校验过程的,可以随意在这个目录中添加文件,比如一些快速批量打包方案就选择在这个目录中添加渠道文件。

    v2 是一种全文件签名方案

    该方案能够发现对 APK 受保护部分进行的所有更改,从而有助于加快验证速度并增强完整性保证。v2 签名机制不存在解压原始数据,签名校验时间显著减少,因此安装时间也相应减少。同时,它是基于 APK 的二进制内存做的签名信息(APK Signing Block 签名块本身不参与加密校验),因此打包后改变 APK 的其他三部分的任何字节都会导致签名校验不通过。这也说明了,zipalign 是要在 apksigner 之前的。

    把 APK 按照 1M 大小分割,分别计算这些分段的摘要,最后把这些分段的摘要在进行计算得到最终的摘要也就是 APK 的摘要。然后将 APK 的摘要 + 数字证书 + 其他属性生成签名数据写入到 APK Signing Block 区块。

    v2签名过程:

  • 相关阅读:
    Qt-快速展开/折叠所有代码段
    【已解决】VS2008下MFC程序如何设置多语言
    (二)Apache log4net™ 手册 - 配置
    一次XGBoost性能优化-超线程影响运算速度
    【云备份|| 日志 day1】项目认识 && 环境准备
    服务器内存一般多大?(服务器内存够用吗)
    idea使用Alibaba Cloud Toolkit实现自动部署
    第6章 java内部类
    Kafka Stream 学习笔记-5 process api
    充电器快充取电芯片XSP06Q+锂电池5A电流快速充电
  • 原文地址:https://blog.csdn.net/cpcpcp123/article/details/127836649