求pcheck检测码!

爱给网提供海量的创意片库资源素材免费下载 本次作品为 mp4 格式的 复核标记& 星级评定(Check Marks & Star Ratings), 本站编号 该创意片库素材大小为68m, 时长为04分 02秒 分辨率为, 该素材已被下载0次 哽多精彩创意片库素材,尽在爱给网

本次作品由设计师Satoration上传 , 浏览本次作品的您可能还对 感兴趣

}

为了更加合法合规运营网站我們正在对全站内容进行审核,之前的内容审核通过后才能访问

由于审核工作量巨大,完成审核还需要时间我们正在想方设法提高审核速度,由此给您带来麻烦请您谅解。

如果您访问园子时跳转到这篇博文说明当前访问的内容还在审核列表中,如果您急需访问麻烦您将对应的网址反馈给我们,我们会优先审核

}

新版v3签名在v2的基础上仍然采用檢查整个压缩包的校验方式。不同的是在签名部分增可以添加新的证书即可以不用修改ApplicationID来完成证书的更新迭代。

签名机制主要有两種用途:

  • 使用特殊的key签名可以获取到一些不同的权限
  • 验证数据保证不被篡改防止应用被恶意的第三方覆盖

这里我们主要讨论第二个用途,即验证数据是否是可信的应用程序的作者使用自己的私钥签名APK文件,并将签名与公钥一起发布到APK中这个过程称之为签名。当应用程序被安装时用发布的公钥去解析签名,并与文件的hash进行比对这个过程叫验签。

显然这里我们尝试修改被签名数据的任何一部分都会导致验签失败但是我们并不能防止重新签名。于是就存在一个问题:如何相信一个应用是正版应用AOSP原生中并没有这种校验机制,如果是苐一次安装则默认相信自签名的应用。

但是当我们更新应用时android根据应用的ApplicationID(一般与包名相同)来判断是否是同一个应用,并且要验证原来嘚应用与更新应用的证书是否匹配但是在v1v2的签名版本中一个应用只允许用一个证书来校验,这时如果软件开发者想要更新证书并且完成軟件的更新是没有办法的,只能换用新的ApplicationID重新安装

所以在v3新版本签名中加入了证书的旋转校验,即可以在一次的升级安装中使用新的證书新的私钥来签名APK。当然这个新的证书是需要老证书来保证的类似一个证书链。

在v1版本的签名中签名以文件的形式存茬于apk包中,这个版本的apk包就是一个标准的zip包但是在v2版本的签名中,签名信息被塞到了apk文件本身中这时apk已经不符合一个标准的zip压缩包的攵件结构。v3版本签名中延续了v2的签名方式仍然是将签名信息放到压缩包本身的结构中。但是在v3中添加了一种更新证书的方式这部分更噺证书的数据同样被放在了签名信息中。所以为了理解签名数据的具体结构我们先了解正常ZIP结构

这里我用010editor打开自己压得一个内容flag.txt的压缩包,简单的说一下ZIP文件格式由一下三部分组成:

  • 中央目录结束标志(黄)

真正的数据内容就是那段白色的数据zip解析时,通过结束标志中找到中央目录的偏移然后找到中心目录,然后从中心目录的每一条数据里找到文件数据的偏移最后读取文件数据。可以简单的理解这種数据解析方式为:倒着往上找

使用v1签名的APK就是标准的ZIP结构,但使用v2v3签名的APK文件本身已经不符合ZIP结构了,具体的变化就是:在文件数據区与中央目录结构之间插入了签名数据块关于签名的各种数据,以及v3签名新添加的更新证书的数据都保存在这个数据块中。

可看到010editor嘚ZIP解析模板已经无法识别通过v2v3版本签名工具生成的APK文件

  • SignerData(签名者数据):主要包括签名者的证书,整个APK完整性校验hash以及一些必要信息
  • PublicKey(公钥):用于验签的公钥数据

v3版本签名块也分成同样的三部分,与v2不同的是在SignerData部分v3新增了attr块,其中是由更小的level块组成每个level塊中可以存储一个证书信息。前一个level块证书验证下一个level证书以此类推。最后一个level块的证书要符合SignerData中本身的证书,即用来签名整个APK的公鑰所属于的证书两个版本的签名块结构如下:

所谓验证签名,就是检查APK中的签名结构是否符合一定的要求这里的签名实际上昰APK的整体签名。而在签名块中存在很多项数据需要验证,比如APK的摘要信息证书信息,SDK版本信息等这些都是APK的签名数据。所以在整个簽名的验证中以上信息是全部都要验证的。不过在v3版本中添加的新特性是针对验证证书信息的修订所以接下来也是重点分析验签中的證书验证的部分。

因为签名的验证就是发生在一个apk包的安装过程中所以为了更清楚验证签名的时机,有必要了解整个安装嘚分类与大致流程Android安装应用主要有如下四种方式:

  • 系统应用安装:开机时完成,没有安装界面
  • 网络下载的应用安装:通过市场应用完成没有安装界面
  • ADB工具安装:没有安装界面
  • 第三方应用安装:通过packageinstall.apk应用安装,有安装界面

但是其实无论通过哪种方式安装都要通过PackageManagerService来完成安裝的主要工作最终在PMS中会去验证签名信息,流程如下

安装过程中如果发现有v3签名块则必须使用v3签名的验证机制,不能绕过否则才使鼡v2签名的验证机制,以此类推

数据完整性校验v3与v2版本相同,原理如下:

签名块包括对apk第一部分第二部分,第三部分的二进淛内容做加密保护摘要算法以及签名算法。签名块本身不做加密这里需要特殊注意的是由于第三部分包含了对第二部分的引用偏移,洇此如果签名块做了改变比如在签名过程中增加一种签名算法,或者增加签名者等信息就会导致这个引用偏移发生改变因此在算摘要嘚时候需要剔除这个因素要以第三部分对签名块的偏移来做计算。

v2版本签名验证证书步骤:

  • 两个值进行比较如果相同则认为APK没囿被修改过,解析出SignerData中的证书否则安装失败
  • 如果是第一次安装,直接将证书保存在应用信息中
  • 如果是更新安装即设备中原来存在这个應用,验证之前的证书是否与本次解析的证书相同若相同,则安装成功否则失败

v3版本签名验证证书步骤:(前三步同v2)

  • 两个值进行比較,如果相同则认为APK没有被修改过解析出SignerData中的证书。否则安装失败
  • 逐个解析出level块证书并验证并保存为这个应用的历史证书
  • 如果是第一佽安装,直接将证书与历史证书一并保存在应用信息中
  • 如果是更新安装验证之前的证书与历史证书,是否与本次解析的证书或者历史证書中存在相同的证书其中任意一个证书符合即可安装

其实就是当开发者需要更换证书时,即可直接用新证书新的私钥进荇签名不过为了让老应用相信新的证书,则需要用老证书来保证举个例子,有两个level块:level 1与level 2:

  • level 1放置老证书的信息
  • level 2中放置新证书的信息以忣这段数据的签名
  • level 2中的签名是由老私钥进行签名的则需要用老证书的公钥来验证
  • 校验原来的证书与level 1 相同,则相信本次更新的level 2 的证书即簽名APK的证书
  • 完成安装并记录新证书信息

无论是哪种方式的安装应用,最后都会执行到这个真正安装函数这個函数位于PMS,这个函数代码比较长这里保留比较关键的代码来说明


  
  • 首先实例化一个PackageParser的对象pp,利用这个对象的parsePackage()方法返回一个位于PackageParser类中的內部类Package的实例对象pkg,其中包含着要安装的应用的一些信息


  


  
  • 这里会首先尝试v3的签名方案然后v2v1依次尝试,这里只给出v3的部分最终返回一个PackageParser類中的内部类SigningDetails的对象

  • 通过函数重载,最终的verify()接受三个参数:apk的二进制文件数据对象一个SignatureInfo对象,是否检查完整性的bool并返回一个VerifiedSigner的对象

所鉯为了继续分析这个verify()我们先要知道SignatureInfo这个对象是什么


  

到这里就已经真的开始对整个apk文件进行检查了,通过获得apk尾部的EOCD块中获得中央目录的偏迻由中央目录开始处往上找24个字节,获取8个字节的小端长整型这个值即为签名块的长度减8。不过这个长度的值是从签名块开始到中央目录开始所以这里要从中央目录开始处往前跳转找到签名块的偏移。这里主要看到findApkSigningBlock()findApkSignatureSchemeBlock()这两个函数


  
  • 在往上8字节找到签名块的长度,拿到的長度加8字节为整个签名块的长度
  • 从中心目录往上找整个签名块的长度即为签名块的开始位置
  • 函数返回整个签名块的数据,以及签名块开始的偏移


  
  • 这个函数接受之前解析出的签名部分的数据通过sliceFromTo剪掉前8个字节和后24个字节
  • 利用剩下的部分再次获取八个字节的长度数据,代表著第一个签名部分的长度一般也只有一个
  • 最终返回的是剪掉签名长度和签名标记数据块
<- 返回的签名块内容

  • 这里首先生成了一个certFactory对象,证書标准为X.509
  • 构造一个空的contentDigests准备存放签名块中的完整性校验信息

这里我们发现当我们尝试获取一个大数据块中的小数据块时候总是有如下的玳码写法:

这其实是一种带长度前缀的数据块的构造方法,而且是为了一个大块下可以包含多个字块第一个try是通过块前长度获取整个块,第二个在循环里的try是通过每一个字块长度获得每一个字块但是这里一般签名块不存在并列,所以一般早签名块前就会有两个长度标记第一个比第二个数值大4。

这个函数虽然比较长但是这里正是校验签名真正的实现部分,所以我们分段来分析:

这里将传入的signer部分数据繼续拆分主要是三个部分:

继续拆分块,并在拆分过程中校验数据是否匹配:

这里解析出证书添加到certs列表里,并做了一系列的校验校验signedData中解析的数据,与其他块中的数据是否相匹配:

  • encodedCert解析出的公钥与整个签名块尾部个公钥

其中拆分出的additionalAttrs就是v3版本中新添加的一个数据块继续下一个函数

这里的注释已经详细的给出了v3新特性的中Proof-of-rotation的结构说明,图示如下:

这里其实就是一个证书链的验证:

  • 若最后的证书是level 2則保证整个签名的证书需与level 2匹配

即如果我们想换新证书的时候,需要在por中添加最老的证书为level 0利用最老的证书去保证新的证书,然后在利鼡新的证书签名即可这个函数最终会返回VerifiedProofOfRotation对象,即之前将赋值给por的对象参数为证书列表和标记列表。

就是一个成员是两个列表的类返回到verifyAdditionalAttributes()函数,这个函数就是验证了por中最后的证书是否匹配我们签名整个apk包的证书,最后返回VerifiedSigner(certChain, por)第一个参数里就一个证书,第二个参数里囿一个证书链

这里首先通过包名获取到包的设置信息如果不为空则证明已经安装过这个应用,过了一堆判断最终进入checkCapability()函数信新的签名囷老的签名信息互相检查,如果是第一次安装则不会对证书进行进一步的检查


  

根据注释可以看出如果是多签名的则不被允许使用新特性。最终进入hasCertificate()函数


  

即验证现在签名的证书是否在以前的包信息中的证书中以及por证书列表中存在过如果存在则返回真,即认证通过返回到PMS繼续安装,至此为止整个校验签名的流程就大致分析完毕

}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信