15、安全与隐私:Android Automotive 安全模型,用户配置文件隔离,数据加密

各位同学,今天我们来聊聊车载系统里最敏感、也最绕不开的话题——安全与隐私。说实话,做手机系统时,安全更多是“防坏人”;但到了车上,安全是“保人命”。Android Automotive 的安全模型,说白了就是一套“谁能在车上做什么”的规则。

15.1 安全模型:从 Linux 内核到 Android 框架

Android Automotive 的安全体系,底层依赖的是 Linux 内核的 DAC(自主访问控制)和 SELinux(强制访问控制)。我刚开始接触车载项目时,总觉得 SELinux 策略文件写起来特别繁琐,动不动就 avc: denied。后来我养成了一个习惯:每次添加新服务,先跑一遍 audit2allow 工具,把缺失的权限自动补全,再手动审查一遍。

嗯,这里要注意:车载系统里,很多服务是系统级常驻的,比如车辆网络服务(Vehicle Network Service)。这些服务的 SELinux 域必须严格限制,不能随便访问用户数据。

核心原则: Android Automotive 的安全模型遵循“最小权限原则”。每个进程、每个服务,只给它能完成工作所需的最小权限。

15.2 用户配置文件隔离:车上不止一个人

你想想看,一辆车可能被家庭多人使用,甚至被租车用户临时开。每个人的设置、联系人、导航历史,都是隐私数据。Android Automotive 通过“用户配置文件”来实现隔离。

每个用户配置文件,本质上是一个独立的 /data/user/<userId> 目录。系统通过 UserManager 来管理这些配置文件的创建、切换和删除。

// 创建一个新用户(例如:访客模式)
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
UserHandle newUser = um.createUser("访客", 0); // 0 表示非管理员

// 切换用户
try {
    um.switchUser(newUser);
} catch (UserManager.UserOperationException e) {
    // 切换失败,常见原因是目标用户正在运行关键服务
    Log.e("AutoSecurity", "用户切换失败: " + e.getMessage());
}

我在项目中遇到过一个问题:用户切换时,后台的导航服务还在跑,导致新用户能看到前一个人的目的地。解决方案是在 switchUser() 之前,先调用 stopUser() 停止所有前台服务。

避坑指南: 我曾经在切换用户时忘记处理 MediaSession,结果新用户一上车,蓝牙自动播放了前一个人的歌单。嗯,这很尴尬。记得在 onUserSwitching() 回调中清理所有媒体会话。

15.3 数据加密:静止时加密,传输时加密

数据加密分两块:存储加密和传输加密。Android Automotive 默认启用 FBE(基于文件的加密)。每个用户的数据,使用独立的密钥加密。

FBE 的核心机制是:每个文件或目录,关联一个 encryption_key。系统启动时,只有解锁屏幕后才能拿到密钥,解密用户数据。

// 检查当前用户是否已解锁(即数据是否可访问)
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
boolean isUnlocked = um.isUserUnlocked();

if (!isUnlocked) {
    // 数据不可访问,不能读取联系人、导航历史等
    // 常见场景:刚开机时,用户还没输入密码
    showLockScreen();
}

传输加密方面,车载系统内部通信使用 Android KeystoreTLS。我建议所有 IPC 调用,尤其是涉及车辆控制信号的,都加上签名验证。

注意: 不要将加密密钥硬编码在代码中。我曾经在客户的代码里看到 String key = "123456",这等于没加密。正确的做法是使用 KeyGenParameterSpec 生成密钥,并存储在 TEE(可信执行环境)中。

15.4 安全架构总览

下面这张图,是我自己总结的 Android Automotive 安全架构。你可以看到,从硬件到应用层,每一层都有对应的安全机制。

Android Automotive 安全架构 应用层 权限检查(Permission Check) | 用户配置文件隔离(UserManager) 框架层 PackageManager | ActivityManager | ContentProvider 安全策略 系统服务层 Vehicle Network Service | 窗口管理 | 输入管理(安全策略) 内核层 SELinux 强制访问控制 | FBE 文件加密 | Keystore(TEE) 硬件安全模块(HSM) TEE(可信执行环境) 安全启动链

15.5 实际项目中的安全实践

最后,我分享几个我在车载项目中踩过的坑,希望能帮你少走弯路。

场景 问题 解决方案
多用户切换 后台服务残留,数据泄露 onUserSwitching 中停止所有前台服务
车辆控制接口 第三方应用恶意调用 使用 signature 级别权限,只允许系统应用访问
日志输出 Logcat 中打印了用户密码 使用 Log.d 时加 if (BuildConfig.DEBUG) 判断
数据备份 备份文件未加密 使用 BackupAgent 时,对敏感数据手动加密
个人习惯: 我每次提交代码前,都会用 lint 检查安全相关的警告。特别是 HardcodedDebugModeExportedContentProvider 这两项,几乎每次都能抓到问题。

好了,关于安全与隐私,今天就聊到这里。记住一句话:在车上,安全不是功能,是底线。下一章我们会深入聊聊车载系统的性能优化,到时候见。


公众号:蓝海资料掘金营,微信deep3321