• Android签名机制简介


    签名机制是Android系统相对于Linux独有的安全机制,本文将对该机制做详细介绍。

    一、介绍

    Android的签名机制主要用在以下两个场合:App更新包的校验和申请手机权限时的权限检查。

    1. 更新包的校验

    用户在升级一款已经安装过的App时,如果程序的修改来自于同一来源,则允许升级安装,否则会提示签名不一致无法安装的提示。

    2. 权限检查

    对于申请权限的 protection level 为 signature 或者 signatureOrSystem 的,会检查权限申请者和权限声明者的证书是否是一致的。

    二、Android证书验证流程

    1. 签名流程

    Android 系统不允许安装没有任何数字签名的应用APK程序,所有应用程序必须使用某个证书进行签名(一般为应用开发者自签名证书)。所以在完成Android程序编写后,需要将程序打包成APK安装文件。首先由应用开发者使用自己的私钥,对整个Android程序进行签名,生成数字签名的文件,将打包签名后的APK文件发布到安卓应用市场。

    %e5%9b%be%e7%89%871

    图1 Android证书验证流程图

    2. 签名校验流程

    用户从市场下载APK安装文件,在真正安装APK前,会首先验证数字签名。具体步骤:

    (a) 首先计算除META-INF文件夹以外所有文件的SHA1摘要值,同META-INF文件夹内的MANIFEST.MF文件中的摘要值做比对。如果不同,则证明源文件被篡改,验证不通过,拒绝安装。

    (b) 计算META-INF文件夹中的MANIFEST.MF的摘要值, 以及MANIFEST.MF中每一个摘要项的摘要值,同.SF文件中的摘要值做比对。如果不同,则证明.SF被篡改,验证不通过,拒绝安装。

    从META-INF文件夹中的.RSA 文件中取出开发者证书,然后从证书中提取开发者公钥,用该公钥对.SF文件做数字签名,并将结果同.RSA文件中的.SF签名进行比对。如果不同,则验证不通过,拒绝安装。

    三、通过逆向APK文件查看APK的签名文件

    对某一个APK文件重名为为RAR压缩文件,打开该压缩文件后就可以看到META-INF文件夹

    %e5%9b%be%e7%89%872

    图2 解压APK文件得到的目录文件

    打开META-INF文件夹可以看到三个数字签名文件MANIFEST.MF,CERT.SF,CERT.RSA

    %e5%9b%be%e7%89%873

    图3 META-INF文件夹中的签名文件

    四、Android签名机制的安全性保证

    1. 对应用安装包完整性的保护

    首先,如果想要改变了apk包中的文件,插入恶意代码。那么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是验证失败,程序就不能成功安装。

    其次,如果对更改的过的文件相应的算出新的摘要值,然后更改MANIFEST.MF文件里面对应的属性值,那么必定与CERT.SF文件中算出的摘要值不一样,照样验证失败。

    最后,如果继续计算MANIFEST.MF的摘要值,相应的更改CERT.SF里面的值,那么数字签名值必定与CERT.RSA文件中记录的不一样,还是失败。

    那么能不能继续伪造数字签名呢?答案是不可能,因为没有数字证书对应的私钥。因为公钥被开发者公开发布了,公钥就确定了,由于公钥与私钥一一对应,所以在修改文件后,没有相应的私钥,无法的到正确的数字证书,那么在应用使用公钥进行校对的时候,就会验证失败。

    2. 对应用更新的保护

    在应用更新时,或者在安卓应用平台校验要安装的应用是否合法(是否是原开发者签名发布的应用),通过比对CERT.RSA中的公钥。由于RSA算法的加密方式,一个密钥对应一个公钥,不会存在多对一的情况,所以根据此可以意识到:

    (a) Android签名机制其实是对APK包完整性和发布机构唯一性的一种校验机制。

    (b) Android签名机制不能阻止APK包被修改,但修改后的再签名无法与原先的签名保持一致。(拥有私钥的情况除外)。

    (c) APK包加密的公钥就打包在APK包内,且不同的私钥对应不同的公钥。换言之,不同的私钥签名的APK公钥也必不相同。所以我们可以根据公钥的对比,来判断私钥是否一致。

    五、FakeID漏洞介绍

    1. 漏洞说明

    Bluebox在2014年7月30日公布了一个关于APK签名的漏洞——FakeID,黑客可以利用该漏洞可以提升权限,突破沙箱限制。

    2.漏洞原理

    一般情况下,我们平时发布的Android应用都是采用自签名的方式,所谓自签名是指公钥证书中Issuer(发布者)和Subject(所有者)是相同的,比如Adobe Flash Player的签书信息如下所示:

    %e5%9b%be%e7%89%874

    图4 Adobe Flash Player的签书信息

    除了通过自签名的方式,我们还可以采用由CA颁发私钥证书进行签发。采用这种方式,最终APK中的公钥证书中,就会包含证书链。这种方式跟签名名的主要区别是最终的公钥证书中,Issuer和Subject是不相同的,而且会存在多于一个证书,证书与证书之间是通过Issuer与Subject进行关联的,Issuer负责对Subject进行认证。

    前面说到,当APK是非自签名时,APK中存在证书链。当安装APK时,系统只会用位于链中最底层的证书对APK文件进行合法性和完整性校验,但并不会验证证书链的有效性。想象这么一个情景:

    (a)开发机上生成一个根证书(记作CA),并用这个证书去颁发一个子证书(记作CLIENT);

    (b)使用这个子证书对APK签名,这时APK中的RSA文件将包含两个证书,分别是CLIENT和CA,其中系统会使用CLIENT对APK文件进行检验;

    (c)对这个RSA文件篡改,把CA修改为Adobe Flash Player的CA(记作FakeCA)。由于系统不会对证书链的合法性进行验证,所以修改后APK,依然可以被正常安装;

    3. 问题所在

    产生FakeID漏洞的根本原因是因为安装APK时,系统没有对证书链进行合法性验证,下面分析一下有漏洞的代码。见代码:

    %e5%9b%be%e7%89%875

    图5 FakeID漏洞所利用的漏洞代码

    代码中遍历证书文件,只要issuer跟遍历的candidates[i].getSubjectDN()相等即可,这个equal只是简单的做了字符串的对比,就直接认为这个是合法的证书,并返回来。

    4. 漏洞补丁

    %e5%9b%be%e7%89%876

    图6 修补漏洞后的代码

    修补后的代码,添加了subjectCert和chainCheck两个参数,添加了证书链的验证。

    5. 漏洞利用

    如果没有修补代码会怎样?我们可以这么构造一个恶意证书:

    (a)开发机上生成一个根证书(记为CA),并用这个证书去颁发一个子证书(记为SIGN)

    (b)然后使用这个子证书为我们即将发布的apk签名,这时APK中的.Rsa文件将包含两个证书,一个是SIGN,一个是CA。并且APK所有的文件都是可以用这个RSA文件验证其合法性的

    (c)对这个RSA文件进行篡改,只修改CA证书的内容(替换后的CA记为FakeCA),不修改证书中的SignerInfo部分,不影响PackageManger在安装前使用SignerInfo.encryptedDigest对APK包数据完整性进行校验

    (d)这个APK可以被成功安装,并且包含两个证书,一个是SIGN,一个是FakeCA

    上文已经提到过,PackageManger在安装APK时并不校验证书链上所有证书的合法性,只要存在被指定的SIGN能够校验APK中所有文件的合法性即可。

    但是签名证书的另外一个功能,验证身份,则受到了这个漏洞的影响。系统中多处使用getPackageInfo获取安装包证书,如果获取到多个证书,通常认为只要有一个证书可信即可。

    具体利用方式,见下面链接:
    http://blogs.360.cn/360mobile/2014/08/04/all-about-fakeid/

    六、参考资料

    1. http://myeyeofjava.iteye.com/blog/2125348
    2. http://www.2cto.com/News/201412/357785.html
    3. http://blog.csdn.net/jiangwei0910410003/article/details/50443505
    4. http://blog.csdn.net/jiangwei0910410003/article/details/50402000
    5. http://blog.csdn.net/l173864930/article/details/38409521

  • 相关阅读:
    数据库主体拥有数据库角色,无法删除
    popupWin类QQ弹出窗口
    使用性能监视器找出硬件瓶颈
    关于反射中Assembly.CreateInstance()与Activator.CreateInstance()方法的区别
    大数据的通用分页总结!
    SQL 注入[转自:微软技术中心]
    【转】 使用Yahoo的公开API做天气预报
    JS对select动态添加options操作
    asp.net “从客户端检测到有潜在危险的Request.Form值” 处理办法
    SQL中索引的原理
  • 原文地址:https://www.cnblogs.com/turn2i/p/10682169.html
Copyright © 2020-2023  润新知