Android的安全性和权限(Security and Permission)(一)
本文档向应用开发者介绍如何使用Android提供的安全行特征。
Android是一个特权分离的操作系统,在系统中运行的每个应用程序都有一个区分系统标识(Linux用户ID和分组ID)。标识的系统部分也被区分不同的身份。因而Linux能够把应用程序以及系统进行彼此分离。
另外,更细粒度的安全特征是通过“权限”机制来提供的,这种机制强制限制了特殊进程所能执行的具体操作,并且给每个URI都设定了方位具体数据片段的权限。
安全架构
Android安全架构的核心设计点是,默认的情况下,没有任何应用程序有权来执行能够对其他应用程序、操作系统或用户带来不利影响的任何操作。包括读写用户的私有数据(如通信录或e-mail)、读写另一个应用程序的文件、执行网络访问、保持设备的唤醒状态等等。
因为Android用沙箱来分离每个应用程序,因此应用程序必须明确要共享的资源和数据。应用程序通过声明来获取它们所需要的基本沙箱所不具备的额外能力。应用程序静态的声明它们所需要的权限,并且Android系统会在安装应用程序时,提示应用程序来同意。Android没有动态(在运行时)授权机制,因为安全的损害会给用户带来复杂的用户体验。
应用程序沙箱不依赖用于构建应用程序的技术。特别是在Dalvik虚拟机中是没有安全边界的,并且任何应用程序都能运行本机代码。所有类型的应用程序,包括Java、原生的以及混合的应用程序,都以相同的方式被放在沙箱中,它们彼此都有相同的安全程度。
应用程序签名
所有的Android应用程序(.apk文件)都必须用一个证书来进行签名,证书的私有键被应用的开发者所持有。这个证书标识了应用程序的作者,它不需要由证书授权机构来签署,这是完全允许的,并且通常Android应用都使用自签名证书。Android中证书的目的是区分应用程序的作者。这样就允许系统接受或拒绝应用程序访问签名级别的权限,以及接受或拒绝应用程序要求获得与另一个应用程序相同的Linux身份的请求。
用户ID和文件访问
在安装时,Android系统会给每个包分配一个不同的Linux用户ID。这个身份标识对于设备上处于运行期间的包会保持不变。在不同的设备上,同样的包可能会有不同的UID,这不重要,重要的是在一个设备上,每个包要有不同的UID。
因为安全是在进程级别上强制发生的,任何两个包的代码通常不会运行在同一个进程中,因此它们需要用不同的Linux用户来运行。能够在每个包的Androidmanifest.xml文件中的<manifest>标签中使用sharedUserId属性,来给它们分配相同的用户ID。通过这样做,这些设置了相同用户ID的包会被视为同一个应用程序,并具有相同的权限。要注意的时,为了保留安全性,只有使用了相同的签名的应用程序(并且申请了相同的sharedUserId属性)才会给分配相同的用户ID。
应用程序存储的任何数据,都会把应用的用户ID分配给它,并且通常其他的包不能访问它。当用getSharedPreferences(String, int)、openFileOutput(String, int)或openOrCreateDatabase(String, int, SQLiteDatabase.CureorFactory)等方法创建一个新的文件时,能够使用MODE_WORLD_READABLE和(或)MODE_WORLD_WRITEABLE标记来允许其他的包来读写这个文件。当设置了这些标记时,这个文件依然被创建它的应用程序所拥有,只是被设置全局的读写权限,以便其他应用程序能够访问它。
使用权限
一个基本的Android应用程序是没有权限跟它关联,这意味着它不能够做任何给用户体验或设备上的数据带来不利影响的事情,要使用设备上那些受保护的功能,必须在应用程序的AndroidManifest.xml文件中包含一个或多个<uses-permission>标签,来声明应用程序需要的权限。
例如,需要监视器接收SMS消息的应用程序,应该指定以下设置:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.app.myapp" >
<uses-permission android:name="android.permission.RECEIVE_SMS" />
...
</manifest>
在应用程序安装时,应用程序申请的权限会通过Android的包安装器来授予,包安装器通过应用程序声明的权限和(或)跟用户进行交互来检查是否应该将对应的权限授予该应用程序。在应用程序运行是,它不会检查权限。也就是说,要么在安装时就给应用程序授予其所申请的权限,使其能够使用这些权限所限定的功能,要么不批准其所申请的权限,使其不能使用这些权限所限定的功能,并用户也不会得到任何提示。
很多时候,由于没有权限而导致的失败,会给应用程序抛出一个SecurityException异常。但是并不保证没有权限的任何地方都会发生这个异常。例如,sendBroadcast(Intent)方法在发送数据时,会检查每个接受器的权限,这个方法调用返回之后,如果有权限失败的情况,也不会收到异常。但是,在几乎所有的场合,权限相关的失败会打印一个系统级日志(log)。
由Android系统提供的权限能够在Manifest.permission类中找到。任何应用程序还可以定义和强制实施它自己的权限,因此这个类中列出的不是所有的可能的权限。
在程序的执行过程中,可在很多地方强制实施一个特殊的权限:
1. 在系统调用的时候,阻止应用程序执行某些功能;
2. 在Activity启动时,阻止其他应用程序的Activity来启动本应用;
3. 在发送和接收广播时,控制谁能接收你的广播或谁能给你发送广播;
4. 在访问并操作一个内容提供器时;
5. 绑定或启动服务的时候。
摘自 FireOfStar的专栏
补充:移动开发 , Android ,