Android安全模型并不是一个单一的防护机制,而是由多个层次共同构成的纵深防御体系。从底层的Linux内核进程隔离,到应用框架层的权限检查,再到SELinux的强制访问控制以及硬件级的密钥保护,每一层都在阻止未授权访问和恶意行为。真正理解这些层次如何协作,是构建健壮Android应用的基础。

一、Android安全模型的分层架构
Android基于Linux内核,因此天然继承了Linux的许多安全特性,例如进程隔离、文件系统权限、用户ID(UID)和组ID(GID)机制。每个Android应用在安装时都会被分配一个唯一的Linux UID,并且通常运行在自己的进程中。这种设计意味着默认情况下,一个应用无法读取另一个应用在/data/data/目录下的私有文件,也无法直接访问其他应用的内存空间。这种隔离是所有上层安全机制的基础,可以防止一个应用直接窥探或修改另一个应用的数据。
除了基本的UID隔离,Android还引入了Binder IPC机制。Binder不仅用于应用组件之间的通信,还会在服务端检查调用方的UID和PID,从而防止未授权的进程冒充合法调用者。例如,系统服务在收到Binder调用时,可以通过Binder.getCallingUid()获取调用方身份,并与声明的权限进行比对。下面的命令可以查看系统中各个进程的UID和名称,帮助理解隔离的实效:
adb shell ps -A -o USER,PID,NAME
在内核之上,Android的安全架构还包含硬件抽象层(HAL)、系统服务层和应用框架层。HAL运行在独立的进程中,并且受SELinux策略约束,即使某个HAL模块被攻破,攻击者也无法轻易访问其他系统资源。应用框架层则提供了权限检查、组件封装和Intent过滤等机制,将底层的安全能力以API的形式暴露给开发者。开发者无需直接操作UID或SELinux上下文,只需要正确声明和使用权限即可。
二、应用沙箱与权限机制
应用沙箱的核心是UID隔离与文件系统权限的结合。每个应用的私有目录/data/data/包名/只对该应用的UID可访问,系统目录则对所有应用只读,而外部存储则根据权限和分区策略开放。这种设计让应用无法读取其他应用保存的SharedPreferences、数据库或缓存文件,从而保护了登录凭证、聊天记录等敏感数据。不过,沙箱并非万能,如果应用自身存在漏洞,例如导出了包含敏感数据的ContentProvider,攻击者仍然可以通过IPC进行访问。
权限机制进一步细化了应用对敏感API和数据的访问控制。开发者必须在AndroidManifest.xml中声明所需的权限,例如相机、定位或通讯录权限。普通权限在安装时自动授予,而危险权限则需要在运行时向用户动态请求,用户可以选择允许或拒绝。下面的XML片段展示了在清单文件中声明权限的写法,注意<uses-permission>标签必须放在<manifest>标签内部:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
对于危险权限,仅声明还不够,必须在运行时检查并请求。以下Java代码展示了检查相机权限并在未授权时发起请求的逻辑:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
} else {
openCamera();
}
权限系统的局限在于,一旦用户授予了某个权限,应用就可以在授权范围内持续使用,用户往往无法感知具体的调用频率。Android 11之后引入了一次性权限和权限自动重置功能,例如定位权限可以只允许本次使用,系统会在一段时间未使用后自动重置未使用的权限。这在一定程度上缓解了权限被滥用的问题,但也要求开发者在每次使用前都重新检查权限状态。
三、SELinux在Android中的强制访问控制
SELinux(Security-Enhanced Linux)是一种强制访问控制(MAC)机制,它在Android 4.3中被引入,并在Android 5.0之后默认以强制模式运行。与传统的自主访问控制(DAC)不同,SELinux即使进程以root身份运行,也必须遵守策略中定义的允许规则。这意味着即使某个系统服务或应用进程被攻破,攻击者也无法随意读取其他文件或访问网络,因为策略会限制该进程的权限。
在SELinux中,每个进程和文件都被赋予一个安全上下文,通常包含用户、角色、类型和级别四个字段。Android主要使用类型(type)来进行访问控制,并通过域(domain)来描述进程类型。例如,普通应用进程通常运行在untrusted_app域,系统应用运行在system_app域,而system_server则运行在独立的域中。可以通过以下命令查看进程的安全上下文:
adb shell ps -Z
SELinux策略由allow规则组成,每条规则规定了源域、目标类型、对象类别以及允许的操作。下面是一个简化的策略示例,表示允许untrusted_app域访问app_data_file类型的文件,并执行读、写和获取属性操作:
allow untrusted_app app_data_file:file { read write getattr };
当应用尝试执行策略不允许的操作时,SELinux会拒绝该操作并在内核日志中记录一条avc: denied消息。开发者或安全研究人员可以通过以下命令查看被拒绝的记录,进而判断是策略过严还是应用行为异常:
adb shell dmesg | grep avc
Android中SELinux策略被拆分为平台策略和供应商策略,以适应不同硬件厂商的定制需求。平台策略定义了Android核心系统的访问规则,而供应商策略则允许设备厂商为自家硬件组件添加规则。这种拆分减少了策略冲突,但也要求厂商在升级系统时确保策略兼容,否则可能导致某些硬件无法正常访问。
四、应用签名与硬件级密钥保护
应用签名是Android安全模型中的重要一环,它确保了APK的完整性和来源可追溯性。每个APK在发布前都必须使用私钥进行签名,系统在安装时会验证签名,确保APK没有被篡改。从Android 7.0开始,系统引入了APK Signature Scheme v2,它不再仅对JAR中的文件进行签名,而是对整个APK文件的二进制内容进行哈希和签名,从而提供了更强的完整性保护。后续的v3方案则增加了密钥轮换能力,允许应用在更新时更换签名密钥而不丢失身份。
开发者可以使用apksigner工具验证APK的签名信息,例如查看签名证书的详细信息:
apksigner verify --print-certs myapp.apk
在应用签名之外,Android还提供了硬件级的密钥保护机制,即Android Keystore系统。Keystore允许应用在可信执行环境(TEE)或安全元件(SE)中生成和存储密钥,密钥的私钥部分永远不会离开安全硬件,普通操作系统甚至应用进程都无法导出密钥。以下代码展示了使用Android Keystore生成AES密钥的方法:
KeyGenerator keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
keyGenerator.init(new KeyGenParameterSpec.Builder("my_key",
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build());
SecretKey key = keyGenerator.generateKey();
除了Keystore,Android还支持文件级加密(FBE)和元数据加密。FBE使用不同的密钥对每个文件进行加密,当设备解锁后,只有在用户解锁凭据验证通过后,对应文件的密钥才能被解密,从而保护用户数据。对于需要存储敏感信息的企业应用,结合Keystore和FBE可以显著降低数据泄露风险,即使设备被物理获取,攻击者也无法在不知道用户密码的情况下读取数据。
Android安全模型应用沙箱SELinux修改时间:2026-08-27 10:11:38