移动端签名机制

1、签名是什么

        要知道签名是什么,先来看为什么需要签名 。大家都知道,在消息通信时,必须至少解决两个问题:一是确保消息来源的真实性,二是确保消息不会被第三方篡改。在安装Apk时,同样需要确保Apk来源的真实性,以及Apk没有被第三方篡改。如何解决这两个问题呢?方法就是开发者对Apk进行签名:在Apk中写入一个“指纹”。指纹写入以后,Apk中有任何修改,都会导致这个指纹无效,系统在安装Apk进行签名校验时就会不通过,从而保证了安全性。进行签名校验,校验通过后才能安装成功。那在这个过程中签名校验的机制是什么?具体校验的是什么内容?我们APP是如何进行签名管理、签名以及发布验证呢?本篇文章将从这几个方面进行介绍。

        要了解如何实现签名,需要了解两个基本概念:数字摘要和数字证书。

1.1数字摘要

        数字摘要是将任意长度的消息变成固定长度的短消息,它类似于一个自变量是消息的函数,也就是Hash函数。数字摘要就是采用单向Hash函数将需要加密的明文“摘要”成一串固定长度的密文,这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。

1.2签名大概过程    

        前面已经说到,可以通过签名来确保数据来源的可靠性和数据的不可篡改性。签名就是在摘要的基础上再进行一次加密,对摘要加密后的数据就可以当作数字签名,在安装Apk需要对签名进行验证,验证通过才能继续安装。

1.3证书

        接收方必须要知道发送方的公钥和所使用的算法。如果数字签名和公钥一起被篡改,接收方无法得知,还是会校验通过。如何保证公钥的可靠性呢?答案是数字证书,系统在安装Apk时并没有校验证书本身的合法性,只是从证书中提取公钥和加密算法,这也正是对第三方Apk重新签名后,还能够继续在没有安装这个Apk的系统中继续安装的原因。

2.签名校验

         Android与iOS签名实现和校验方式有所不同,以下将分平台介绍两端各自签名校验过程。

2.1Android签名方式

        Android 的签名方案,发展到现在,已经支持三种应用签名方案:

  • v1 方案:基于 JAR 签名。
  • v2 方案:APK 签名方案v2,在 Android 7.0 引入。
  • v3 方案:APK 签名方案v3,在 Android 9.0 引入。

        目前我们APP大多采用V1+V2签名方式,由于V2方式不支持低于7.0的版本,因此,为了低版本正常安装,先使用v1签名再使用v2签名。在实际应用中,优先校验v2签名,没有或不存在校验机制时,校验v1签名。在主工程build.gradle中定义了签名配置。

2.1.1V1签名

         其中由于V1签名生成的文件是META-INF中MAINIFEST.MF CERT.RSA CERT.SF,那这三个文件之间是如何对APK进行签名的呢,一张图足以说明整个签名过程:

        根据上面签名过程,V1签名校验流程具体是:

  • 首先校验cert.sf文件的签名

        计算cert.sf文件的摘要,与通过签名者公钥解密签名得到的摘要进行对比,如果一致则进入下一步;

  • 校验manifest.mf文件的完整性

        计算manifest.mf文件的摘要,与cert.sf主属性中记录的摘要进行对比,如一致则逐一校验mf文件各个条目的完整性;

  • 校验apk中每个文件的完整性

        逐一计算apk中每个文件(META-INF目录除外)的摘要,与mf中的记录进行对比,如全部一致,刚校验通过;

  • 校验签名的一致性

        如果是升级安装,还需校验证书签名是否与已安装app一致。

        在校验步骤中,任何一步校验出错,都会导致APP签名校验不通过,无法安装APP或无法覆盖安装,例如:

  • 如果篡改apk内容,会导致校验apk每个文件完整性失败,因为此文件hash值会被更改,与.mf和.sf中不同;
  • 如果篡改apk内容,同时篡改.mf以及.sf摘要信息,在校验.sf签名是也会失败;
  • 如果将apk内容和签名信息一同篡改,相当于对apk进行重新签名,他会相当于一个新APP安装到系统中,无法进行覆盖安装。

2.1.2V2签名

        通过V1签名我们可以知道,V1签名是在apk文件中增加META-INF目录,而V2签名是全文件签名方式,可以对.apk所有受保护的内容进行签名保护。APK文件结构上来看,由3个部分构成:ZIP 条目的内容、ZIP 中央目录、ZIP 中央目录结尾。V2方案为加强数据完整性保证,不在ZIP 条目的内容和ZIP 中央目录中插入数据,选择在两者之间插入一个APK签名分块,从而保证了原始zip(apk)数据的完整性。

        第1、3、4部分的完整性是通过内容摘要来保护的,这些摘要保存在signed data分块中,而signed data分块的完整性是通过签名来保证的。

        根据上面签名方式原理,V2签名校验流程具体是:

  • 找到APK签名分块并验证以下内容:

          APK 签名分块的两个大小字段包含相同的值。

           ZIP 中央目录结尾紧跟在ZIP 中央目录记录后面。

           ZIP 中央目录结尾之后没有任何数据。

  • 找到APK 签名分块中的第一个APK 签名方案 v2 分块。如果 v2 分块存在,则继续执行第 3 步。否则,回退至使用 v1 方案验证 APK。
  • 对APK 签名方案 v2 分块中的每个signer执行以下操作:

    从 signatures 中选择安全系数最高的受支持 signature algorithm ID。安全系数排序取决于各个实现/平台版本。

    使用公钥并对照signed data 验证 signatures 中对应的 signature。

    验证 digests 和 signatures 中的签名算法 ID 列表(有序列表)是否相同。这是为了防止删除/添加签名。

    使用签名算法所用的同一种摘要算法计算 APK 内容的摘要。

    验证计算出的摘要是否与 digests 中对应的 digest 相同。

    验证 certificates 中第一个 certificate 的 SubjectPublicKeyInfo 是否与公钥相同。

  • 如果找到了至少一个 signer,并且对于每个找到的 signer,第 3 步都取得了成功,APK 验证将会成功。

2.1.3V1、V2签名对比

我们APP目前都向支持V2签名转变,那为什么要支持新的签名机制呢?根据两种签名机制的原理分析,我们不难看出,V2签名是优于V1签名,具体对比如图所示:        

签名方式 效率方面 安全方面
V1签名
需对所有文件进行hash校验,速度较慢
不够安全
只保证了APK内各文件的完整性,APK其它内容的完整性未保证
V2签名
只需进行一次hash校验,速度快
较安全
除保证了APK内各文件的完整性,APK中数据区、中央目录和中央目录结尾记录的完整性均得到了保证
签名校验耗时,体现在安装耗时上,同一部手机,安卓7,安装同样的包,v2签名的apk安装耗时是v1签名的1/3

 

2.2iOS签名方式

         iOS采用双层代码签名校验

        生成签名:

        在Mac开发机器生成一对公私钥,这里称公钥L,私钥L;

        把公钥L上传到苹果后台,用苹果后台里的私钥A去签名公钥L。得到一份数据包含了公钥L以及其签名,把这份数据称为证书,和一份描述文件;

        编译完一个 APP 后,用本地的私钥M对这个APP进行签名,同时把从苹果服务器得到的 Provisioning Profile 文件打包进APP里,文件名为embedded.mobileprovision。

        认证过程:

        在安装时,iOS 系统取得证书,通过系统内置的公钥 A,去验证证书的数字签名是否正确;

        通过系统内置的公钥 A,解密拿到描述文件,查看里面的设备列表时候包含当前设备;

        验证证书后确保了公钥 L 是苹果认证过的,再用公钥 L 去验证 APP 的签名;

        验证描述文件里的AppID是否与当前App的AppID一致,App申请的功能时候与描述文件一致。

3.签名管理与发布验证

3.1签名管理

       目前android与iOS端证书文件均由RD提供,QA统一严格管理。

        android证书布置在打包机器,代码工程配置使用,打出不同类型包。

        iOS证书存放打包机器,在运行打包命令时使用,打出不同类型包。

3.2发布验证

       目前打包平台所包含包类型如下:

3.2.1Android端

证书类别 特点 有效期 说明 使用场景
debug证书 不同app使用同一debug证书,但不能覆盖安装 1年 可进行debug调试,debug包未做混淆,不得外传 单元测试,debug调试
release证书 不同app可能相同release证书 根据生成配置 调试麻烦,集成时需要验证代码混淆是否造成bug 集成测试,发布市场

        使用release包发布,首先验证已开启代码混淆,另外需要验证覆盖安装,保证证书一致。

3.2.2iOS端

证书类别 特点 有效期 说明 使用场景
App Development 可以制作多个副本分发给多台设备 1年 只可以使用Xcode进行真机调试 本地调试
InHouse 只能有一个,不能制作副本分发到多台电脑 3年 可以在任意一台iOS设备上安装,肆意的安装可能会遭到封号 单元测试,通过第三方托管发布内部渠道
AdHoc 非越狱的设备也能够安装,该设备的UDID已经添加到开发者账号所在的组中 单元测试,集成测试
AppStore 1年 可直接提交App Store或在越狱机上使用 集成测试,发布App Store

        使用release或者inhouse包发布,需要验证覆盖安装,保证证书一致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章