英文原文:http://source.Android.com/devices/tech/security/index.html
引言
________________________________________
安卓是一个现代化移动平台,它设计的初衷就是实现真正的“对外开放”。安卓的各种琳琅满目的应用程序利用高端的硬件和软件资源,乘本地和云端数据的春风,凭借整个平台,给消费者带来了极具革命性的、有价值的信息。为了保护这宝贵的价值,安卓平台必须提供一个异常安全的应用程序环境,以保证用户的安全、用户数据的安全、应用程序的安全、设备的安全以及网络的安全。
要保证一个开放平台的安全性,健壮的安全体系和严格的安全方案是必须的。安卓是多层安全结构,这为开放的平台提供了灵活性,同时为平台的所有用户提供了保护。安卓的架构设计思路无时无刻不为开发者考虑。其安全控制为开发者减轻了重担。安卓安全技术开发者可以轻易的工作于,甚至依赖于安卓这个灵活多变的安全控制体系。同时,对安全领域不太熟悉的开发者,安卓将提供默认的保护措施。
安卓无处不在地考虑着使用设备的用户。安卓提供了可视化的界面来告诉用户应用程序如何工作,如何通过这些应用程序控制安卓平台。当然,安卓的这个架构设计也存在一些缺陷,攻击者可以利用这些缺陷来试试许多破坏活动过,比如社会工程学攻击:让设备使用者安装恶意程序,以实现对已经安装的其它应用程序的攻击。当然了,幸运的是,安卓的设计思想不仅可以减少这种攻击发生的可能性,而且,即便攻击成功,也会最大程度的限制恶意程序对系统的危害。
本文档概括了安卓安全方案的目标,描述了安卓安全体系结构的基础,并且回答了许多系统架构师和安全分析师提出的各种安全相关的问题。本文档主要关注安卓核心平台的安全特征,不讨论某个特定应用程序的安全问题,例如浏览器、短信平台的安全问题等等。至于如何编译安卓系统、部署系统到设备上或者如何开发应用程序,都不在本文档的讨论之内,它们在别的地方都有讨论。
背景
________________________________________
安卓为移动设备提供了一个开放的平台和应用程序环境。安卓架构的主要模块是:
- 设备硬件:安卓可以跑在许多硬件设备上,包括智能手机、平板电脑、机顶盒等。安卓不会去理会底层用的什么处理器,但是他会充分利用处理器的安全特性,例如ARM v6的eXecute-Never特性。
- 安卓操作系统:安卓操作系统是建立在linux内核之上的。所有的设备资源,像摄像头功能、GPS数据、蓝牙功能、打电话模块和网络连接等功能,都是通过Linux操作系统访问的。
- 安卓应用程序运行时:安卓的大部分应用程序都是通过java语言编写的,并且运行在达尔维克虚拟机上。然而,许多应用程序,包括核心安卓服务和应用程序都属于“本地应用程序”或者“本地库”。但,不论达尔维克虚拟机还是本地应用程序,都运行在相同的安全环境上,即应用程序沙盒模型。
安卓应用程序拥有一个指定的文件系统分区,在该分区写私其有数据,包含数据库资源和原始文件资源。安卓应用程序扩展了安卓核心操作系统。安卓应用有两种主要的来源:
- 预装应用程序:安卓包含一些系统预装的应用程序,包括电话、邮件、日历、浏览器和联系方式等。这些应用是用户应用程序,同时,也向设备提供系统最关键的功能,以便其他应用程序去访问。预装应用可以作为安卓开放平台的一部分,也可以由OEM为特定设备开发。
- 用户安装应用:安卓提供了一个开放的开发环境,用以支持任何第三方应用。谷歌应用商场提供给用户数以万计的应用程序支持。
谷歌提供了一揽子云端服务,并对任何兼容的安卓设备提供使用。主要服务为:
- 谷歌商场:谷歌商场是一个服务的集合体,它允许用户直接通过安卓设备或者PC网络去搜索,安装并且购买应用。谷歌商场让普通应用开发者轻易的触及到应用购买者以及潜在的应用购买者。此外,谷歌商场提供了一个社区审查、应用许可证验证、应用安全扫描和其他的安全服务。
- 安卓升级服务:安卓升级服务向安卓设备提供了新增的功能和安全升级,包括通过PC网络或者通过OTA升级。
- 应用程序服务:应用程序框架,允许安卓应用使用云端服务,例如备份应用程序数据和设置、云端到设备的推送消息C2DM(目前已经被GCM替代)。
安卓安全方案综述
________________________________________
在安卓设计之初,安卓核心开发团队认识到,在云端服务支持下,为了在安卓平台打造一个严格的应用程序和设备生态系统,他们必须构想出一个健壮的安全的模型。结果,经过一个完整的开发周期,安卓依然成为了一个专业安全程式。安卓核心团队观察了其他移动平台、桌面平台和服务器平台对诸多安全问题的防范和反应,并分析了其他平台是如何创建一个安全方案来处理系统的缺陷。
安卓安全方案的关键组成部分包括:
- 设计思路审查: 安卓核心团队在对安卓系统安全方面的考虑在开发周期的初始阶段就已经开始了。他们的设计思想是创造一个丰富的、可配置的安全模型。基于整合在系统体系架构内部的恰当的安全控制策略,安卓平台的每一个主要功能都须通过工程和安全资源进行审查。
- 渗透性测试和代码审查: 在平台开发过程中,安卓平台和开源组件必须进行强有力的安全审查。这些安全审查工作由安卓安全团队,谷歌信息安全工程团队和许多独立的安全顾问执行。这些安全审查工作的目标是:在安卓平台正式开放之前,尽可能的寻找系统薄弱环节和系统缺陷,此外,还可以模拟来自谷歌外部的安全专家的各种类型的安全分析。
- 开源和社区审查:安卓开源工程可以让任何感兴趣的团体进行广泛的安全审查。安卓使用了先进的开源技术,我们知道开源技术经历过非常严格的外部安全审查,例如Linux内核。谷歌商场为普通用户和企业提供了一个论坛,该商场可以向普通用户直接提供应用的相关信息。
- 事件响应:即便有这些安全预警机制,安全问题也时有发生,这也正是为何安卓工程要建立了一个完整的安全响应机制。专职的安卓安全团队在时刻不停的注意着安卓安全社区和普通的安全社区的任何关于安卓系统潜在缺陷的相关讨论。如果发现有合理的提议,安卓团队对此有一个响应机制,可以保证对安卓系统缺陷的及时修正,把恶意程序对安卓用户的潜在威胁降低到最小程度。
安卓平台安全体系
________________________________________
安卓力求成为移动平台的最安全和最具可用性的操作系统,将传统操作系统安全控制重新定义如下:
- 保护用户数据
- 保护系统资源(包括网络)
- 提供应用程序执行的隔离
为了实现这些目标,安卓提供了以下关键安全功能:
- l 通过Linux内核在操作系统级别提供健壮的安全特性
- l 强制性的应用程序沙盒机制
- l 安全的进程通信机制
- l 应用程序签名机制
- l 应用程序定义和用户授权机制
下面逐一介绍上面谈到的和没有谈到的一些安卓平台的安全功能。图1展现了安卓软件栈不同级别的安全组件。每一个组件假设其下的各个组件已经得到合适的保护。除了小部分安卓系统的代码以root身份运行,所有其他运行于Linux内核之上的代码都受到应用程序沙盒机制的严格限制。
图1:安卓软件栈
系统和内核等级的安全性
在操作系统级别,安卓平台提供了Linux内核的安全特性,此外,提供了一个安全的进程间通信机制,来保证运行于不同进程上的应用程序之间的通信。这些操作系统级别的安全特征可以保证即使是Native代码也在应用程序沙盒机制的管控之下。不论是应用程序包含了恶意行为,还是黑客对普通应用程序的破解,安卓都会阻止这种对其他应用程序、系统本身和设备本身的破坏行为。
Linux安全
________________________________________
安卓平台的基础是Linux内核。Linux内核本身就已经得到广泛应用多年,并且是应用在数以万计的对安全性能要求极高的环境下。鉴于已经过多年研究、被数以万计的开发者修正的这样一个事实,Linux内核已然变成为一个稳定的、安全的、可以被许多企业和安全开发者所信任的一个平台。
作为一个移动平台的基础计算环境,Linux内核提供给安卓许多关键的安全特征:
- 一个基于用户的权限管理模型
- 进程隔离机制
- 可以扩展的安全进程通信机制
- 可以从Linux内核移除非必要的和潜在的不安全模块
作为一个多用户操作系统,Linux内核的一个非常重要的安全目标是隔离不同用户的私有资源。
Linux内核安全核心思想是保护用户资源不被其他用户侵犯。因此Linux内核:
- 阻止用户A去读取用户B的文件
- 证用户A不会耗尽用户B的内存资源
- 保证用户A不会耗尽用户B的CPU资源
- 保证用户A不会破坏用户B的设备(例如电话、GPS、蓝牙设备等)
应用程序沙盒机制
________________________________________
安卓平台利用Linux的基于用户的保护策略这样一个有效的方法,来确认和隔离应用程序的资源。安卓系统为每个应用程序指派一个独一无二的用户ID,并且以这个用户ID运行在一个隔离的进程上下文中。这个方法不同于其他操作系统(包括传统的Linux操作系统配置),传统的操作系统的情况是多个应用可以相同的用户(ID)权限运行。
这样就建立了一个内核级别的应用程序沙盒。内核加强了应用程序之间的安全性,在进程级别上通过标准的Linux工具加强了系统的安全性,例如用户ID,组ID,这些属性被分配到应用程序中。默认情况下,应用程序之间不能交互,并且应用程序访问操作系统也要受到限制。如果应用程序A,在不经过权限允许的情况下,去恶意读取应用程序B的数据,或者拨打电话(电话模块是一个独立的系统应用模块),那么操作系统将会阻止应用程序A的行为。因为应用程序A没有得到合适的用户特权。沙盒机制其实很简单,它可以对应用程序进行审计,它是基于发展了数十年的UNIX风格的用户进程隔离机制和文件权限访问机制而产生的。
应用程序沙盒机制是基于Linux内核,这个安全的模型可以延伸到Native代码和操作系统应用程序。图1中占现了所有位于Linux内核之上的应用软件,包括操作系统库、应用程序框架、应用程序运行时和所有运行于沙盒机制中的应用程序。我们知道在一些平台上,开发者往往仅被局限在一个特殊的开发框架、应用程序接口和计算机语言中,目的是加强安全。但是在安卓平台上,没有任何类似的限制。鉴于此,Native代码和解释性的代码一样安全。
在一些操作系统中,内存错误通常会对设备的安全造成危害。在安卓平台,情况并非如此,因为所有应用程序和他们的私有资源是在系统级的沙盒机制保护之下的。在建立于操作系统上的权限管理机制下,一个内存错误仅仅允许在特定的应用上下文执行任意代码。
像所有安全特征一样,应用程序沙盒机制也不是坚不可摧的。然而,要攻破一个经过合适配置的应用程序沙盒,就必须攻破Linux内核的安全机制。
系统分区和安全模式
________________________________________
系统分区包含安卓内核,也包括操作系统的各种库、应用程序运行时、应用程序框架,和各种应用。这个分区的属性是只读的。当一个用户启动到安全模式时,只有核心的安卓应用是可以使用的。这保证了普通用户可以启动他们的手机到一个对第三方应用自由的环境里面。
文件系统访问权限
________________________________________
在一个类UNIX操作系统环境下,文件系统权限访问可以保证一个用户不能改变或者读取其他用户的资源。在安卓系统中,每个应用程序以独一无二的用户ID运行。除非开发者明确的暴漏文件给其他应用程序,否则一个应用创建的文件是不能被其他用户改变或者读取的。
Security-Enhanced Linux
________________________________________
安卓使用了SELinux的相关特性来进行强制文件访问控制。建立一个强制访问控制的安全环境(MAC)。参考:
http://source.android.com/devices/tech/security/se-linux.html(英文)
(译文)
密码学支持
________________________________________
安卓提供了一揽子密码学支持的应用程序接口给应用开发者。这些接口包括标准的、通用的密码学应用实例,包括:AES, RSA, DSA, and SHA。另外,安卓为更高级的协议,例如SSL和HTTPS也提供了应用程序接口。安卓4.0引入了KeyChain链,允许应用程序为私钥和可信链使用系统可信的存储空间。
内存安全管理加强版
________________________________________
安卓包括许多安全特性,这使许多安全问题很难攻破。安卓SDK、编译器、和操作系统工具,可以保证普遍存在的内存崩塌问题难以攻破,这包括(本节推荐看原文,因为实在不太好翻):
Android 1.5
- ProPolice 用以阻止栈缓冲溢出
- 安全safe_iop减少整数溢出
- OpenBSD Dlmalloc的扩展可以阻止双free缺陷,并且阻止块加固攻击。块加固攻击是一个普遍存在的攻击堆错误的方法
- 在内存分配的过程中,OpenBSD calloc可以阻止整数溢出
Android 2.3
- 格式化字符串的缺陷保护
- 基于硬件的No eXecute,可以阻止代码在栈和堆上执行
- Linux 移植空指针解除引用特权增强(在4.1版中得到了加强)
Android 4.0
- 一种针对缓冲区溢出的安全保护技术
Android 4.1
- PIE (Position IndependentExecutable) support 位置独立执行的支持
- Read-only relocations /immediate binding (-Wl,-z,relro -Wl,-z,now) 只读分配、立即绑定
- dmesg_restrict enabled (avoidleaking kernel addresses) 避免泄漏内核地址
- kptr_restrict enabled (avoidleaking kernel addresses) 避免泄漏内核地址
Android 4.2
- FORTIFY_SOURCE for systemcode FORTIFY_SOURCE for系统代码
Root一个设备
________________________________________
默认情况下,安卓系统,只有内核和一小部分核心应用程序是以root身份运行的。安卓是不会阻止一个拥有root权限的用户或应用程序去修改操作系统资源、内核和任何其他应用程序的。
通常情况下,root拥有访问所有应用程序和所有应用程序资源的权限。改变安卓设备的权限,使得其获取root权限,以root权限访问应用程序,这样的行为会增加安全隐患,相当于把整个设备暴漏给恶意应用和一些潜在的应用缺陷。修改安卓设备的能力对一个工作在安卓平台上的开发者是非常重要的。
在许多安卓设备上,用户有解锁引导加载程序的能力,这样,用户就可以轻易的更换操作系统景象。而更换了的操作系统可以允许设备拥有者获取root访问权限,以达到调试应用和系统组件的目的,即,获取root权限后,可以通过安卓应用程序接口访问某些一般情况下(普通权限下)应用不能访问的安卓功能。
在一些设备上,一个控制着物理设备和一条USB线缆的自然人可以安装一个新的操作系统,该操作系统提供root权限给一个普通用户。为了保护任何现存的用户数据不受到侵害,引导加载程序解锁机制需要: 引导加载程序其中一个解锁步骤就可以擦除任何现存用户数据。
通过破解内核的一个bug或者一个安全漏洞,root行为可以绕过这些保护。
用存储在设备中的密钥对数据进行加密,对于root用户来讲,根本保护不了应用程序私有数据,因为root用户可以访问这些似有数据。应用程序可以通过加密来对数据增加一层保护,这个加密过程中使用的密钥是存储在设备之外的,例如,在一个服务器上,或者一个用户密码中。当密钥还没有准备好之前,这个方法可以提供暂时的保护,但是在一些情况下,密钥必须提供给应用程序,那么这个时候root用户就可以访问这个密钥了。
一个更加健壮的,保护数据不被root用户侵犯的途径是:通过硬件方法解决。OEM们可能会选择实施一些硬件解决方案来限制对一些特殊内容的访问,例如视频回放的数字版权保护,或者谷歌钱包的进场通信相关的可信存储。
如果出现设备丢失或者被盗的情况,在一个安卓设备上进行全文件系统加密时是使用设备密码来保护加密密钥的,所以通过修改引导加载程序或者操作系统去访问用户的数据是不行的,因为没有用户的设备密码。
用户安全功能
________________________________________
文件系统加密
安卓3.0及其后续版本提供全文件系统加密,所以所有用户数据可以在内核中进行加密,通过AES128块设备加密(dmcrypt)(基于密码分组链接和ESSIV:SHA256)。
加密密钥是通过一个取自于用户密码的密钥获得的,这防止了在没有用户设备密码的情况下对存储数据的非授权访问。
为了有效抵御系统密码猜测攻击(例如““rainbow tables” or brute force”),密码最好通过标准的PBKDF2算法(而不是通过解密文件系统密钥),由随机盐(虽然感觉憋足,但不知道该怎么准确来翻译,那还是直译吧)和哈希值(SHA1)组成,。
为了有效抵御词典密码猜测攻击,安卓提供了复杂密码规则,该规则可以由设备管理者来设置,由操作系统来增强保护。文件系统加密需要用户密码,基于模型的屏幕锁没有得到支持。
关于文件系统加密的更多详细资料请参考:
https://source.android.com/devices/tech/encryption/android_crypto_implementation.html
密码保护
________________________________________
安卓可以进行密码安全配置,即在访问一个设备之前首先验证用户提供的密码,如果密码不对则不允许访问。在阻止对设备的非授权使用之外,该密码还会为整个文件系统加密保护密钥。密码或者复杂密码规则的使用与否由设备管理者决定。
设备管理
________________________________________
安卓2.2及其后续版本提供了安卓设备管理的应用程序接口,这就在系统级别提供了设备管理的功能支持。例如,内建安卓邮件应用使用应用程序接口去改进Exchange的支持。通过邮件应用,Exchange的管理者可以加强密码策略——这包括设备上的字母和数字密码、数字pin。管理者也可以远程地擦除(默认情况下,恢复工厂模式)丢失或者失窃的设备上的数据。
除了在安卓系统级应用中用设备管理之外,设备管理应用程序接口对第三方设备管理解决方案提供者也是开放的。应用程序接口的详细资料请参阅:
https://developer.android.com/guide/topics/admin/device-admin.html
安卓应用安全
应用的组成部分
________________________________________
安卓为移动设备提供一个开放的平台和应用环境。核心操作系统是基于Linux内核。安卓应用大部分是用java语言编写的,并且运行在达尔维克虚拟机上。然而,应用程序也可以写成Native代码。应用程序是通过一个后缀为apk的单个压缩文件进行安装的。
安卓应用的组成部分别是:
- AndroidManifest.xml: 是一个控制文件,它告诉系统如何处理上层的组件(activities, services, broadcast receivers, and content providers下面都有介绍)在一个应用中。这里也指定了需要哪一个权限。
- Activities: 一个activity通常是一段完成单一用户任务的代码。它通常包含对用户显示的用户界面,但也不是必须得显示用户界面,因为有些应用是没有用户界面的。特别讲一下,应用的众多活动中总有一个是应用的入口点。
- services:服务是运行在后台的一段代码。它可以运行在自己的进程上下文中,或者在其他应用进程的上下文中。别的组件绑定一个服务,并且通过远端的调用激活一个方法。服务的一个典型例子是多媒体播放器:即使用户退出多媒体播放的用户界面,用户也同样可以保持音乐的播放。即使用户界面已经退出视线,服务仍保持音乐的继续播放。
- Broadcast Receiver: 是一个实例化的对象,当操作系统或者其他应用调用intent(进程间通信机制的媒介)的时候,它就派上用场了。例如,应用程序可以注册一个广播接收器作为低电状态的消息接收器,收到低电消息后,做出某个响应。
安卓权限模型:访问受保护的应用程序接口
________________________________________
安卓的所有应用程序都运行在应用程序沙盒机制中,这在本文档的前面已有介绍。默认情况下,一个安卓应用仅仅可以访问有
限的系统资源。安卓管理类应用对系统资源的访问,如果使用不当或者被恶意利用,这会影响用户体验,网络使用和数据的安全。
这些对应用的制约(或者称为限制)以不同的方式表现在安卓系统中。安卓故意不提供某些应用程序接口,这样可以限制应用的许多能力,来防止其接触一些敏感资源(例如,目前尚没有任何直接操作SIM卡的应用程序接口)。在一些情况下,应用程序的隔离运行提供了一个安全的措施,因为每个应用的数据存储也都是隔离的。在另外一些情况下,这些敏感的应用程序接口只能由特定的且可信的应用程序使用,并且,通过一个安全机制,即权限访问机制,而受到保护,。
这些受保护的应用程序接口包括:
- 摄像头功能
- GPS位置信息
- 蓝牙功能
- 电话功能
- 短信/彩信功能
- 网络连接功能
这些资源仅仅可以通过操作系统来访问。要在设备上使用这些受到保护的应用程序接口,应用程序必须在manifest中定义这种能力。每当安装一个应用时,系统会弹出一个对话框给用户,上面显示着:各项权限请求清单和询问用户是否要继续安装该应用的字样。如果用户继续安装,系统就会认为设备的拥有者允许了该应用的所有权限请求。
一旦获得授权,只要得到成功安装,则该应用所提出的权限请求就被施加于应用中。为了避免用户的思维混乱,系统将不会再次通知用户:是否要授权给该应用。并且,核心操作系统预装的应用或者被OEM打包进来的应用不会从用户那里申请什么权限。如果应用卸载掉了,这些权限也就随着被移除了,所以如果再次安装该应用的时候会再次显示画面:询问用户是否同意应用的权限申请,如果同意则继续安装。
在设备设置中,用户可以看到之前安装的应用程序的权限设置,用户也可以全局关闭应用的一些功能,例如禁止GPS、收音机或者WIFI等。
如果应用程序尝试着去使用一个受保护的功能,而且这个受保护的功能没有在manifest中进行声明,系统将会抛出一个权限访问失败的安全异常出来。受保护的应用程序接口可以把对系统的欺诈行为的可能性降到最低程度。如图2所示,当安装应用时,系统会默认弹出应用程序的各种权限申请的条目,来让用户分析,是否要继续安装。
系统默认权限的详细描述请参阅:
https://developer.android.com/reference/android/Manifest.permission.html
应用程序可以通过申明的方式来让其他应用程序来使用自己的某些权限。当然,这样的权限没有在上面给出的连接中列出。
当定义一个权限时,一个保护等级属性告诉系统用户是如何被应用程序告知需要哪些权限的,或者谁被允许拥有这个权限。具体如何生成和使用应用程序特殊权限,下面这个链接中有详述:
https://developer.android.com/guide/topics/security/security.html
有一些设备的功能,例如发送短信广播的intents,这是对第三方应用不可用的,但是可以被OEM预装的应用使用。它们使用签名或者系统权限。
用户怎么认知第三方应用
________________________________________
安卓会竭尽全力为用户分析第三方应用,并告知用户第三方应用都哪些权限。在安装任何应用之前,用户可以看到应用程序对各种权限的请求。安装之后,安卓不会再次提示用户对应用提出的权限请求进行授权。
在安装时,显示各种权限请求是很有必要的。这使用户有机会主动的去审核应用本身、开发者和应用功能的相关信息,并由此决定,该应用是否满足了用户的预期要求。同时,这样的权限请求功能对一部分用户是非常重要的:在尚没有对某个应用形成一个成熟的认知或者经济的安心托付时,这样的权限请求功能对普通用户是非常重要的。
其他一些平台使用不同的方法去实现这种权限申请机制,即在每一个会话开始的时候,或者在应用程序运行的时候,用户则得到通知——权限请求。安卓的绝妙之处在于可以使得用户自由的选择自己喜爱的应用。当然,每一次安装都提示用户是否允许权限请求会让用户的使用节奏慢下来,这也降低了安卓极佳的用户体验。但是,在安装应用的时候提示用户再次审查应用的各种权限请求,可以给用户多一个选择,而不去安装不喜欢的应用。
同时,根据对用户界面的研究,对于突然弹出的对话框,普通用户的第一反应就是去点击OK。安卓的安全目标之一就是研究重要安全信息,这些重要安全信息最好不要通过对话框表示,因为用户极有可能忽略对话框上的内容,而直接点击OK。通过仅仅提供一次至关重要的安全信息(也就是数只有最重要的安全信息才弹出对话框提示信息),用户才更可能去分析他们到底在说些什么。
当然,也一些平台不显示应用程序的任何功能性的信息。这个方式使用户不能直接弄清楚应用程序的相关功能。虽然,安卓权限模型允许许多用户轻易的去访问应用层序的相关信息,然而,在安卓平台,也不是所有用户都可以得倒全部通知的。
例如,料想不到的权限请求(比较冷门的权限请求)会使更多老练的用户,在GooglePlay,询问一些关于应用程序功能的关键问题,并且分享它们的关心点,在Google Play,所有用户都可以看到这些信息。
谷歌地图安装时权限请求 | Gmail安装时权限请求 |
| |
图2 应用程序的权限请求
进程间通信
________________________________________
不同进程之间可以使用传统的类UNIX机制来进行通信。例如文件系统、本地sockets或者信号灯。然而,Linux的基本权限管理机制仍然发挥着作用。
此外,安卓提供了新的进程间通信机制:
- Binder:一个轻量级的高性能进程通信机制,包括进程内和进程间通信。Binder的实现是基于Linux驱动的,参见:
https://developer.android.com/reference/android/os/Binder.html
- 服务:服务(上面已经谈过了)可以提供许多接口供开发者使用,但需要用binder来进行调用
- Intent:intent是一个简单的消息目标,它代表了一个“意愿”,去做某件事情。例如,如果一个应用程序想要显示网页,它“表达”自己的“意愿”(intent),通过生成一个intent实例并发送给系统,去查阅URL。然后,系统去寻找网页浏览器的代码,告诉这部分代码如何来处理这个intent,并且运行之。Intents也可以被用来在系统范围内发指定的广播,例如“通知”,参见:XXX
- 内容提供者:内容提供者是一个数据的存储仓库,它提供了在设备上访问数据的途径,一个经典的例子是:内容提供者用于访问用户的联系方式列表。应用程序可以访问由其他应用通过内容提供者来共享出来的数据。参见:
https://developer.android.com/reference/android/content/ContentProvider.html
虽然存在其他进程间通信方式,例如网路套接字或者全局可写文件,但还是建议使用Android进程间通信框架。鼓励安卓开发者使用安全的方法进行开发,这有助于避免安卓安全缺陷所引出的一系列问题。
费用敏感的应用程序接口
________________________________________
费用敏感的应用程序接口其实就是一个可能会使用户或者网络产生费用的功能接口。安卓平台把费用敏感的应用程序接口放在了一个由系统控制的列表里面。第三方应用如果想使用这些接口,必须得到用户的授权。这些应用程序接口包括:
- 电话
- 短信/彩信
- 网络/数据
- 应用内部账单
- 进场通信访问
安卓4.2添加了对短信的进一步控制。如果某应用程序要发送一个短信到某短号的时,该短号绑定一个额外付费服务,安卓将会向用户发送一个通知,此时用户可以选择是否允许这个应用发送短信。
SIM卡的访问
________________________________________
第三方应用对SIM卡的底层访问是不被允许的。系统负责管控对SIM卡的所有操作,包括访问sim卡内的个人私有信息(联系方式)。应用程序也不能访问AT命令,因为这部分由射频接口层来专门负责管理。射频管理层对上层提供了NO个接口来访问这些命令。
个人私有信息
________________________________________
安卓把一部分应用程序接口放在受保护的接口清单里面,其中就包括对用户私有数据的访问。在使用的过程中,安卓设备在用户安装的第三方应用中积累用户数据。如果某个应用程序要分享这些信息,必须使用安卓系统权限审核机制来保护用户数据,而不受第三方应用侵害。
图3:只有通过系统的权限检查才能访问敏感用户数据
系统内容提供者有可能包含个人或者私人身份识别的信息,例如联系方式、日历都是在身份识别信息权限允许的情况下生成的。
这给了用户一个明确的暗示(信息的类型),该信息可以提供给应用程序。在安装的过程中,第三方应用可以提出权限申请来访问这些资源。如果得到允许,这个应用就可以安装,并且拥有在任何时候访问数据的权限。
任何应用程序,如果有收集个人私有信息,默认情况下,这些信息仅能被该应用访问。如果一个应用通过进程通信将自己的数据共享给其他应用,这个经过授权的应用可以将权限机制应用在进程间通信机制中(这是操作系统的加强功能)。
敏感数据输入设备
________________________________________
安卓设备往往会提供一些敏感数据输入设备(外部设备),并且允许应用程序控制它们去和周围的环境进行交互,例如摄像头、麦克风或者GPS。如果应用要访问这些设备,必须显式地通过安卓系统权限进行申明。例如,在安装时,包安装器将会提示用户是否允许对某种感应器(sensor)的访问。
如果应用想知道用户的位置信息,则需要相应的权限去访问用户的位置。在安装的时候,包安装器会提示用户是否允许该应用访问位置信息。不论在什么时候,如果用户不想任何应用访问自己的位置信息,那么用户可以到设置里面的“位置与安全”栏目,禁止使用无线网络和GPS卫星定位服务。这将会禁止任何应用访问用户的位置信息。
设备元数据
________________________________________
安卓竭力禁止对某些数据的访问,这些数据实际上是不敏感的,但重要的是这些数据间接地揭示了用户的特征、用户喜好以及用户使用设备的风格——这些数据就是所谓元数据。
默认情况下,应用程序没有访问操作系统日志、浏览记录、电话号码,或者硬件/网络ID信息的权限。如果在安装时应用请求访问这些信息,包安装器将会提示用户是否要允许该应用访问这些所谓元数据。如果用户不授权,那么应用将不会继续安装。
应用程序签名机制
________________________________________
在不用声称复杂的接口和权限的情况下,代码签名允许开发者确认应用程序的作者,并且升级他们自己写的应用。每一个运行在安卓平台上的应用,必须由开发者签名。如果尝试在未签名状态下安装应用程序,该行为将会被谷歌商场或者安卓包安装器无情的拒绝。
在谷歌商场中,应用签名机制作为一个桥梁,使谷歌和开发者彼此获得信任。因为,开发者知道到,他们编写的应用程序被普通用户下载并运行在手持设备上的过程中,该应用程序时完整的,没有经过篡改的。此外,开发者也要对其开发的应用的任何行为负有直接责任。
实际上,安卓应用签名是把应用程序放置在应用程序沙河中的第一步。签名过的应用程序的证书定义哪一个用户ID和哪一个应用程序相关联。不同的应用以不同的用户ID运行。应用程序签名机制可以确保,除了通过良好的IPC机制,否则应用程序不能访问另外应用程序的资源。
当应用程序安装包安装在安卓设备上时,安装包管理器会验证,APK是否经过合适的签名,是否具有合适的证书。如果证书(或者,准确的讲,证书中的公钥)和密钥匹配(该密钥用于对任何其他APK进行签名),则新的APK可以在manifest文件中指定,它自己将会和其他类似签名的应用安装包共享同一个UID。
应用程序可以通过第三方(OEM,工厂主或者其他应用商场)签名或者自签名。安卓可以通过自签名证书来进行代码签名,该证书可由开发者在没有外部支持或者权限的情况下生成。应用程序没必要使用一个权威机构进行签名。安卓目前不会为应用程序证书执行CA验证。
当保持不同的用户ID和应用程序沙盒时,应用程序也可以在签名保护层级声明安全权限,限制其他以相同证书签名的应用的访问。通过共享用户ID,两个应用之间可以保持紧密的联系。如果两个或者两个以上的应用程序以同一个开发者的密钥签名,那么这两个应用(这些应用)可以在它们的manifest文件中申明共享用户ID。
应用程序验证
________________________________________
安卓4.2及其后续版本支持应用程序验证。用户可以选择使能“Verify Apps”,这样一来,应用必须由一个应用程序验证器验证之后,才能安装。App验证可以警告用户:提醒他们是否在安装一个恶意应用,如果一个应用包含恶意代码,那这个验证机制可以阻止安装。
数字版权管理
________________________________________
安卓平台提供了一个可扩展的DRM(数字版权管理)框架,这可以让应用程序,根据证书限制,对受到版权保护的内容进行有效管理,DRM框架支持许多设计思路,设备所支持的DRM设计工作留给了设备生产商来做。
安卓DRM框架应部署在安卓系统的两个层面上(见下图):
- DRM框架应用程序接口,通过安卓应用框架,对上层应用是开放的,并且跑在达尔维克虚拟机上。
- Native 代码DRM管理器,部署DRM框架,并提供了响应的接口给DRM插件(代理)来处理版权的管理和多种DRM方案的解密。
图4:安卓设备上数字版权管理的体系结构
安卓升级
安卓提供系统升级,以实现安全方面和功能扩展方面的更新。
在大多数安卓设备上,有两种升级系统的方法:OTA升级和side-loaded升级。
- OTA方式需要隔一段时间才能升级一次,或者由OEM和运营商向所有设备一次性推送,这取决于OEM和经销商,它们什么时候提供升级包了,你的手持终端才可以升级。
- Side-loaded升级方式比较自主一些,OEM和经销商可以为用户提供一个网络站点来下载zip格式的升级包,下载到用户的PC机或者直接下载到用户的手持设备上。一旦升级包拷贝或者下载到sd卡上时,安卓就可以辨认到升级包,并验证它的完整性和真实性,然后自动升级设备。
如若有危险的系统缺陷出现,且该缺陷的发现者负责任地报告给了谷歌,或者AOSP工程,那么安卓安全团队将走下面的工作程序:
1、如果出现了问题,安卓团队仅会通知签署了NDAs的企业,并且开始讨论问题的解决方案。
2、代码的持有者负责问题修正的开头工作
3、安卓团队将会修正安卓安全相关问题
4、发布了的修正补丁只可以由签订了NDA(保密协定)的OHA成员使用
5、安卓团队会在AOSP上公开发布补丁。
6、OEM(代工)或者运营商会推送一个升级服务给客户。
我们都知道,OHA成员和谷歌都有签订NDA(保密协定)。该协定规定,任何一个OHA成员如若发现了一个安卓安全问题,绝不可以将其私自公之于众(如果擅自公开,则会让用户处于极度危险之中)。大家都知道,许多OHA成员在他们生产的安卓设备上运行他们自己的代码,例如bootloader、wifi驱动和射频模块等。一旦安卓安全团队察觉到某个OHA成员写的代码里面存在安全问题,他们将会及时和该OHA成员进行有效沟通,来快速准确的找到修正该问题的处理办法。然而,OHA成员如果真的写了错误的代码(有安全隐患),必须是负责修正问题主要责任人。
如果有人不负责任地暴漏出安卓的危险的系统缺陷(例如,这个缺陷被公布在了某一个公开的论坛上,而没有任何警告措施),那么谷歌和AOSP将会尽最大可能,快速生成一个安全补丁来解决这个问题。,经测试无问题之后,这个补丁将会公开发布(对任何开放手机联盟成员)。
谷歌开发者年会(2011),许多开放手机联盟(OHA)成员,承诺在设备卖出之后继续对设备提供18个月的升级。这一举动向用户提供了访问安卓近期的新功能的机会,当然,这也包括安全方面的相关升级。
任何安卓开发者、安卓使用者或者安全研究者,都可以通过发送电子邮件给:security@android.com来通知安卓安全团队,它们发现的潜在的安全问题,。
如果你愿意,你们的交互可以通过安卓安全团队PGP密钥来加密,参见:
https://developer.android.com/security_at_android_dot_com.txt
其它资源
- 关于AOSP的相关信息可参考:
https://source.android.com
- 安卓应用开发者相关信息:
https://developer.android.com
- 安卓安全团队可以通过邮箱地址security@android.com来联系(有什么问题可以直接发给他们,但不知道回复的效率怎样,本人海没有试过)。
- 安全相关信息遍布于AOSP开发者站点的角角落落,一个地方比较适合初学者,位于:
https://developer.android.com/guide/topics/security/security.html
- 为开发者准备的关于安卓安全的常见问题(FAQ),位于:
https://developer.android.com/resources/faq/security.html
- 一些为开发者提供的关于安卓安全的最好的实践,位于:
https://developer.android.com/training/articles/security-tips.html
- 讨论安卓安全话题的社区资源,位于:
https://groups.google.com/forum/?fromgroups#!forum/android-security-discuss