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 Keystore 和 TLS。我建议所有 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 检查安全相关的警告。特别是 HardcodedDebugMode 和 ExportedContentProvider 这两项,几乎每次都能抓到问题。

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


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