Android 一直都支持外部存储配件(如 SD 卡),但由于预期的无常性以及为传统外部存储设备只提供最低限度的数据保护,因此这些配件一直以来仅限于简单的文件存储。Android 6.0 推出了合并外部存储媒介(使其可以像内部存储设备一样使用)的功能。
注意:在搭载 Android 7.0-8.1 的设备上,文件级加密 (FBE) 无法用于可合并的存储设备。在使用 FBE 的设备上,必须将新添加的存储媒介(例如 SD 卡)用作传统存储设备。
运行 Android 9 及更高版本的设备可以使用可合并的存储设备和 FBE。
当合并外部存储媒介时,系统将对其进行格式化和加密处理,以便一次只在一台 Android 设备上使用。由于该媒介与合并它的 Android 设备紧密关联,因此可以安全地为所有用户存储应用和私密数据。
当用户将新的存储媒介(如 SD卡)插入到可合并的位置时,Android 会询问他们想要如何使用该媒介。他们可以选择合并该媒介,这样的话,系统会对该媒介进行格式化和加密处理,或者也可以继续按原样将其用于简单的文件存储。如果他们选择合并媒介,平台会询问是否将主要共享存储内容(通常装载在 /sdcard 上)迁移到新合并的媒介上,从而腾出宝贵的内部存储空间。不同于因使用 MBR 而限制为 2TB 的传统存储设备,可合并的存储设备使用 GPT,因而文件存储空间上限约为 9ZB。
只有当开发者通过 android:installLocation 属性指示提供支持时,才能将应用放置在合并的存储媒介上。新安装的受支持的应用将自动放置在具有最多可用空间的存储设备上,用户可以在“设置”应用中在存储设备之间移动受支持的应用。移动到已合并媒介的应用在媒介弹出时被记住,并在重新插入媒介时返回弹出前的状态。
安全性
平台会为每个合并的设备随机生成加密密钥,并将其存储在 Android 设备的内部存储设备中。这样可以有效地使得合并的媒介与内部存储设备一样安全。密钥与合并的设备(基于合并的分区 GUID)相关联。
如果设备配置为使用其内部存储设备上的文件级加密 (FBE),可合并的存储设备会同时使用 FBE 和元数据加密。否则,可合并的存储设备会使用全盘加密 (FDE)。
合并设备的磁盘布局紧密对应内部数据分区,包括 SELinux 标签等。当在 Android 设备上支持多用户时,合并的存储设备也通过与内部存储设备相同的隔离级别支持多用户。
由于合并的存储设备的内容与合并该设备的 Android 设备密切相关,加密密钥不应可以从父设备中进行提取,因此该存储设备无法装载到其他位置。
如果您的设备使用的是 FBE,请参阅 FBE 文档和元数据加密文档,了解如何在可合并的存储设备上配置 FBE 和元数据加密。
性能和稳定性
应该只考虑合并位于稳定位置(如电池盒内或防护盖后面的插槽)的外部存储媒介,以避免意外的数据丢失或损坏。尤其是,绝不应该考虑合并连接到手机或平板电脑的 USB 设备。一种常见的例外情况是连接到电视类设备的外部 U 盘,因为整个电视机通常安装在一个稳定的位置。
当用户合并新的存储设备时,平台将运行基准测试,并将其性能与内部存储设备进行比较。如果所合并设备的速度明显慢于内部存储设备,则平台将警告用户体验可能会受到影响。此基准根据常用 Android 应用的实际 I/O 行为得出。目前,AOSP 实现只会在超出单个阈值时警告用户,但是设备制造商可以进一步做出调整,例如在存储卡的运行速度非常缓慢时完全拒绝合并。
合并的设备必须使用支持 POSIX 权限和扩展属性的文件系统(如 ext4 或 f2fs)进行格式化。为了获得最佳性能,建议基于闪存的存储设备使用 f2fs 文件系统。
在执行周期性空闲维护时,平台将向合并的媒介发出 FI_TRIM(就像对待内部存储设备那样)。目前的 SD 卡规范不支持 DISCARD 命令;不过,内核会回退到使用 ERASE 命令,SD 卡固件可以选择使用该命令来实现优化目的。
测试
如需测试可合并的存储设备是否正常工作,请运行以下 CTS 测试:
cts-tradefed run commandAndExit cts-dev \
-m CtsAppSecurityHostTestCases \
-t android.appsecurity.cts.AdoptableHostTest
如需在设备没有内置插槽或正使用 USB 连接器进行有效的 adb 连接时验证 U 盘和 SD 卡的行为,请使用以下命令:
adb shell sm set-virtual-disk true