9.5 Android安全机制" class="reference-link">9.5 Android安全机制
道高一尺魔高一丈,自古以来就没有什么绝对的安全,所以Google也建立起一层层的壁垒,保护Android的核心安全,免遭外界的攻击。下面我们来看看Android中的这些安全机制。
9.5.1 Android安全机制简介" class="reference-link">9.5.1 Android安全机制简介
安全不管在哪个平台、哪个语言中,都是非常重要的一环。Android开发者在Android系统中建立了五道防线来保护Android系统的安全。
9.5.1.1 第一道防线
代码安全机制——代码混淆proguard。
由于Java语言的特殊性,即使是编译成Apk的应用程序也存在被反编译的风险。而proguard则是在代码层面上对Android应用程序App的第一重保护,它可以混淆关键代码、替换命名让破坏者阅读困难,同时也可以压缩代码、优化编译后的Java字节码。
9.5.1.2 第二道防线
应用接入权限控制——AndroidMainifest文件权限声明、权限检查机制。
任何应用程序App在使用Android受限资源的时候,都需要显示向系统声明所需要的权限,只有当一个应用App具有相应的权限,才能在申请受限资源的时候,通过权限机制的检查并使用系统的Binder对象完成对系统服务的调用。但是这道防线也有着先天性不足,如以下几项。
- 被授予的权限无法停止
- 在应用声明App使用权限时,用户无法针对部分权限进行限制
- 权限的声明机制与用户的安全理念相关
Android系统通常按照以下顺序来检查操作者的权限。
首先,判断permission名称。如果为空则直接返回PERMISSION_DENIED。
其次,判断Uid。如果为0则为Root权限,不做权限控制;如果为System Server的Uid则为系统服务,不做权限控制;如果Uid与参数中的请求Uid不同,则返回PERMISSION_DENIED。
最后,通过调用PackageManagerService.checkUidPermission()方法判断该Uid是否具有相应的权限。该方法会去XML的权限列表和系统级的platform.xml中进行查找。
通过上面的步骤,Android就确定了使用者是否具有某项使用权限。
9.5.1.3 第三道防线
应用签名机制——数字证书。
Android中所有的App都会有一个数字证书,这就是App的签名,数字证书用于保护App的作者对其App的信任关系,只有拥有相同数字签名的App,才会在升级时被认为是同一App。而且Android系统不会安装没有签名的App。
9.5.1.4 第四道防线
Linux内核层安全机制——Uid、访问权限控制。
Android本质是基于Linux内核开发的,所以Android同样继承了Linux的安全特性,比如文件访问机制,Linux文件系统的权限控制是由user、group、other与读(r) 、写(w) 、执行(x)的不同组合来实现的。同样,Android也实现了这套机制,通常情况下,只有System、root用户才有权限访问到系统文件,而一般用户无法访问。
9.5.1.5 第五道防线
Android虚拟机沙箱机制——沙箱隔离。
Android的App运行在虚拟机中,因此才有沙箱机制,可以让应用之间相互隔离。通常情况下,不同的应用之间不能互相访问,每个App都有与之对应的Uid,每个App也运行在单独的虚拟机中,与其他应用完全隔离。在实现安全机制的基础上,也让应用之间能够互不影响,即使一个应用崩溃,也不会导致其他应用异常。
虽然通过以上的五道防线,仍然不能100%保证Android的核心安全,但却可以在最大程度上给破坏者增加破坏难度。从另一方面来说,这些破坏者的破解也正是推动Android安全机制逐渐健全的动力。
9.5.2 Android系统安全隐患" class="reference-link">9.5.2 Android系统安全隐患
虽说Android建立了N道防线来抵御破坏者的入侵,但是因为没有绝对的安全,所以在Android中也经常会找到一些突破防线的方法。
9.5.2.1 代码漏洞
这个问题存在于世界上所有的程序中,没有谁敢保证自己的程序永远不会有Bug、有漏洞,所以遇到这种问题,大家只能尽快升级系统OS版本、更新补丁,才能杜绝利用漏洞的攻击者。比如Android的LaunchAnyWhere、FakeID这些Bug,就是在代码编写的时候产生的漏洞,因此要防范这样的攻击,只有期待官方补丁才能修复了。
9.5.2.2 Root风险
Root权限是指Android的系统管理员权限,类似于Windows系统中的Administrator。具有Root权限的用户可以访问和修改手机中几乎所有的文件。“Root”在一段时间内一度成为Android的代名词,“无Root,不Android”。的确,Root掉手机后,可以解锁很多普通用户无法完成的工作,如限制各个应用App的数据流量、系统文件管理、自定义修改系统等,但同时手机的安全性也会因此大打折扣。随着Android系统越来越完善,Root的必要性也越来越低,普通用户在不Root的情况下,完全可以正常使用大部分App。需要Root权限的大多为一些开发者,由于开发的需要,不得不将手机Root。而Root后的手机,就少了一层Linux的天然屏障,整个系统核心就完全暴露在入侵者面前,在你没有察觉的情况下大肆破坏。所以,针对普通用户,希望都尽量不要Root手机以免带来不必要的损失。
9.5.2.3 安全机制不健全
由于Android的权限管理机制并不完美,所以很多手机开发商,通常会在ROM中增加自己的一套权限管理工具来帮助用户控制手机中应用的权限,如三星手机中的应用程序许可,如图9.12所示。
图9.12 三星手机安全管理
9.5.2.4 用户安全意识
用户对于安全隐患的觉察力也是保护手机安全的一个重要因素。用户可以通过在正规应用市场下载应用、并在安装应用时通过列出来的应用权限申请信息来大致判断一个应用的安全性,比如曾经非常热门的“XX神器”,其实没有一点技术含量,无非是在你安装了App后遍历你的联系人,并发送带有下载链接的短信而已。当用户在安装不明来源的App时,如果一个娱乐类型的App在声明权限时不仅需要获取联系人信息,还要获取发送短信权限,这时就应该有所警惕。如果还不放心,用户也可以在市场上下载一些安全类App,如LBE安全大师、360安全等,虽然这些安全类App会加重系统的负担,但为了安全也还是值得的。
9.5.2.5 Android开发原则与安全
众所周知,Android与iOS系统一个非常显著的区别就是一个是开放系统一个是封闭系统,开放自然有开放的好处,技术进步快、产品丰富,封闭也有封闭的好处,安全性高、可控性高。Google本着开源的精神开放了Android的源代码,但随之而来的各种安全问题也让Android饱受诟病,过度的开放与可定制化,不仅造成了Android的碎片化严重,同时也给很多不法应用以可乘之机。但可喜的是,随着Android的发展日益壮大,Google也在着手处理开发与安全的问题,相信在不久的将来,这一矛盾会越来越小。
9.5.3 Android Apk反编译" class="reference-link">9.5.3 Android Apk反编译
Android的应用程序Apk文件,说到底也是一个压缩文件,那么可以通过解压缩,获得里面的文件内容。让我们先来找一个Apk文件,然后使用解压缩工具,比如winRar、7-Zip等进行解压,最后就会得到一些文件、文件夹,如图9.13所示。
图9.13 Apk文件系统
解压之后我们看见了不少熟悉的东西,但是当点进去的时候,你就会发现资源文件等xml文件,基本都无法打开,即使打开也是如图9.14所示的乱码。这些乱码就是经过Android加密过的文件。更关键的是,竟然找不到源代码文件夹src。只能在res文件夹中查看非XML的图片资源文件,不过,有些应用会把图片也加密处理,这样你就连图片也看不见了。
图9.14 加密过的文件
既然直接解压Apk文件是无法获得正常的应用程序,那么来看看如何使用正确的方法反编译应用程序。
首先请出三个重量级的工具,如图9.15所示。
图9.15 反编译工具
这三个工具分别负责反编译不同的部分。
9.5.3.1 apktool
首先来反编译Apk中的XML文件,利用apktool_2.0.0b7.jar。
先在命令行下进入到它所在的文件夹目录,如图9.16所示
图9.16 进入apktool目录
然后对test.apk执行反编译命令,如图9-17所示。
图9.17 执行反编译命令
格式非常简单,指定d参数(decode),并写入要反编译的Apk目录。执行后,在该目录下生成一个对应Apk名字的文件夹,如图9.18所示。这时候再进入test文件夹,即可查看相关的反编译出来的代码,如图9.19所示。
![]() | ![]() |
| 图9.18 生成反编译文件 | 图9.19反编译出来的文件 |
打开res中的XML文件,如图9.20所示。
图9.20 反编译出来的代码
此时可以正确地查看这些XML文件而不是之前的乱码了。这个工具在汉化软件的时候非常有用,可以提取资源文件并进行汉化,然后执行如图9.21中所示命令重新打包回去即可。
图9.21重新打包
重新打包的命令与解码的命令相似,只是需要将d改为b,并选择前面解码生成的文件夹。执行该命令后,在文件夹下就会生成两个新的文件夹,如图9.22所示重新打包的Apk就在dist目录下,如图9.23所示。
![]() | ![]() |
| 图9.22 重新打包的文件夹 | 图9.23 重新打包的Apk |
下一步,解决Source Code。
9.5.3.2 Dex2jar、jd-gui
这次需要剩下的Dex2jar和jd-gui两位“大神”了,如图9.24所示。
图9.24 Dex2jar、jd-gui
先回到最开始用解压缩工具解压Apk后的那个文件夹,文件夹中有一个非常重要的文件,即如图9.25所示的dex文件。
图9.25 classes.dex文件
这个文件就是源代码打包后的文件,将它复制到dex2jar-0.0.9.15的根目录下,然后执行进入dex2jar-0.0.9.15的目录并执行如图9.26所示代码。
图9.26 反编译dex文件
可以看到Dex Zjar在后台飞快的分析着,分析过程如图9.27示。
图9.27 分析dex文件
最后在dex2jar-0.0.9.15的目录下生成了一个jar文件,如图9.28所示。
图9.28 分析生成jar文件
当获取了jar文件之后,就轮到jd-gui上场了,打开jd-gui,并选择file-open file,并选择刚刚生成的classes-dex2jar.jar文件。此时,就可以查看相关的源代码了,如图9.29所示。
图9.29 jar文件中的代码
为了保护这个App,我们就不展开看具体的代码了,只找一个通用的部分代码让大家看看,如图9.30所示。
图9.30 反编译出来的代码
通过以上工具的帮助,完美地反编译了应用程序。不过反编译虽好,可不能过度哦,一切断电反编译都应该建立在学习的基础上,而不是破坏、盗取。
9.5.4 Android Apk加密" class="reference-link">9.5.4 Android Apk加密
由于Java字节码的特殊性,使得它非常容易被反编译。因此,为了能够对编译好的Java Class文件进行一些保护,通常会使用ProGuard来对Apk进行混淆处理,用无意义的字母来重命名类、字段、方法和属性。当然,ProGuard不仅仅可以用来混淆代码,还可以删除无用的类、字段、方法和属性,以及删除没用的注释,最大限度地优化字节码文件。
在Android Studio中,可以非常方便地使用ProGuard,在Gradle Scripts文件夹下,打开build.gradle(Module: app)文件,显示如下所示。
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'),
- 'proguard-rules.pro'
- }
- }
这里的minifyEnabled属性就是控制是否启用ProGuard的开关,这个属性以前叫做runProguard,在AS1.1中将其改为minifyEnabled,将这个属性设置为true,即可打开ProGuard功能。proguardFiles属性用于配置混淆文件,它分为两个部分,一个是系统默认的混淆文件,它位于<SDK目录>/tools/proguard/proguard-android.txt目录下,大部分情况下,使用这个默认的混淆文件就可以了;后面一部分是项目中自定义的混淆文件,可以在项目的App文件夹下找到这个文件,在这个文件里可以定义引入的第三方依赖包的混淆规则。配置好ProGuard之后,只要在使用AS导出Apk时,即可生成混淆。
