最近觉得在K20Pro上运行MIUI EU版体验不错,既得到了原版硬件驱动的支持,由得到了谷歌全家桶的体验(距离原生还是差很远,但原生与兼容性不可兼得,只能舍原生而找兼容性)。于是今天将原来的Mix2也换成了MIUI EU,在同步设置的时候发现没有开全盘加密,于是便开启。尝试了两次全都卡住了,经过一系列搜索,最终发现解决之道。
准备工作
刷机嘛,手机上什么TWRP之类的第三方Recovery就不用说了,其次要准备好Mix2的MIUI EU,我使用的稳定版,版本是V12.0.1.0.PDECNXM_v12-9
。之后还要准备谷歌的platform-tools
,主要是其中的adb
。最后再来一个文本编辑器就齐活了。
流程
首先四清或全清,总之就是要干干净净的,然后通过卡刷刷入MIUI EU的ROM。然后不要重启进系统,而是直接重启到第三方Recovery中。
在第三方Recovery中挂在System
分区,打开ADB,拿到系统的fstab,该文件在Linux中指导内核挂载分区。安卓9使用如下命令:
adb pull /system/vendor/etc/fstab.qcom
根据安卓版本的设备的不同,该文件的位置和后缀名可能不同,需要自行寻找,有可能需要挂在Vendor
分区。执行完命令之后手机中的fstab.qcom
就会上传到电脑中。将其中的encryptable=ice
修改成fileencryption=ice
,其他的不要改动,尤其留意修改时使用的符号或空格等,修改不对可能导致手机无法启动。并且该方法只在第一次启动系统前有效。
修改完成后使用如下命令将修改下载回手机:
adb push fstab.qcom /system/vendor/etc/fstab.qcom
完成后重启手机,进入系统。并在初始化设置中设置密码,随后手机将启动开启全盘加密。初次启动系统耗时较长,因为要加密全屏,请耐心等待。如果超过一小时还未启动,则考虑重新开始流程,应该是修改过程出了问题。
验证
- 系统设置中显示手机已经加密
- 重启到第三方Recovery之后需要输入密码才能查看文件内容
原理
之前提到过,fstab
是现代Linux系统中指导内核挂载磁盘分区的重要文件。以我们刚刚修改的为例:
#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
/dev/block/bootdevice/by-name/userdata /data ext4 noatime,nosuid,nodev,barrier=1,noauto_da_alloc wait,check,reservedsize=128M,fileencryption=ice,quota
根据注释,第一个参数指定了挂载设备的名称,在Linux等PC机上,挂载的对象通常是/dev/sda/sda1
之类的,而这里/dev/block/bootdevice/by-name/userdata
则表示手机中实际存储用户数据的分区。第二个参数表示挂载到文件系统中的哪个位置:/data
,即挂在后我们通过/data
就能访问到原来位于/dev/block/bootdevice/by-name/userdata
上面的数据。第三个参数表示该文件系统是什么格式的,这里是ext4
,是一种常见的Linux下的格式,类似于Windows上的NTFS
或者Fat32
。
第四个参数指定了内核以何种方式挂载。例如其中的noatime
告诉内核,挂载后不要在访问文件的时候更新文件的访问时间,一方面加快了访存速度,另一方面也减少了写入次数,提高了存储器的寿命。而诸如nodev
和nosuid
则是为了提高安全性。
而第五个参数则是指定安卓的文件系统管理器如何挂载磁盘。例如quota
,是允许文件系统管理器针对该分区启用统计数据。其他参数姑且不谈,本文中起到关键作用的fileencryption
正是出现在此列。
在安卓5的时代,最先引入的是全盘加密,但是全盘加密有一个问题,就是手机启动后,用户未输入密码前,手机的全部数据都是加密的,用户只能拨打紧急电话或者输入密码解锁。如果用过水货HTC的话,或许会对一个白底界面有印象:输入密码解锁手机,或者拨打紧急电话。如果密码输入错误超过30次,那么手机将会自动清空数据。
文中被修改的encryptable
标志则是在那个时候引入的。这种全盘加密带来了诸多不便,首当其冲的便是闹钟功能,因为用户没有解密,所以闹钟在手机关闭后完全不起作用。于是为了解决这个问题,谷歌引入了文件级加密:在启用了直接启动特性的设备上,系统可以直接进入界面,这使得诸如闹钟之类的应用可以发挥作用。这种特性的基础便是文件级加密,它与全盘加密的区别在于,文件级加密的基本单位是文件,在逻辑上仍然可以识别出独立的文件,而不知道密码的情况下无法知晓文件内容;而全盘加密则是以盘块或盘块簇为单位,在存储器级别进行加密,如果不解密,则根本无从知晓其上的文件系统,就更不要说识别文件了。而fileencryption
正是在这个时候被引入的,根据谷歌官方的介绍,用法如下:fileencryption=[加密模式]
,小米指定的是ice
,而谷歌官方解释如下:
如果不使用内嵌加密硬件,则对于大多数设备推荐设置为
fileencryption=aes-256-xts
。如果使用内嵌加密硬件,则对于大多数设备推荐设置为fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized
。在没有采用任何形式的 AES 加速的设备上,可以设置fileencryption=adiantum
,从而用 Adiantum代替 AES。在搭载 Android 10 或更低版本的设备上,也可以使用
fileencryption=ice
来指定使用FSCRYPT_MODE_PRIVATE
文件内容加密模式。Android 通用内核未实现该模式,但供应商可使用自定义内核补丁程序实现该模式。该模式生成的磁盘格式因供应商而异。在搭载 Android 11 或更高版本的设备上,不允许再使用该模式,而必须使用标准加密格式。
我在想,除了小米自己实现的,如果使用标准加密格式,对于速度有什么影响呢。由于对于小米Mix2的硬件信息所知甚少,因此我实际上有刷了4次系统来分别测试速度,每次对应上面的一种加密。软件使用CPDT Benchmark。
测试数据如下:
加密方法 | 4MB顺序写入 | 4MB顺序读取 | 4KB随机写 | 4KB随机读 |
---|---|---|---|---|
无加密 | 156.86MB/s | 506.11MB/s | 19.15MB/s | 13.62MB/s |
ice | 156.50MB/s | 425.07MB/s | 19.24MB/s | 12.92MB/s |
其中使用aes-256-xts:aes-256-cts:inlinecrypt_optimized
和adiantum
后无法启动系统,大概率是因为内核不支持。而aes-256-xts
倒是能启动进入系统,但是卡在了登录谷歌账号上,只要进入到登陆界面,Google Play就崩溃,无法继续配置,重启后进不去系统。看起来MIUI用的内核比较精简,只有厂商自己实现的加密算法。值得一提的是,Mix2使用的是安卓9,或许更新的安卓版本会支持。
于是只测试了厂商实现的算法,与不使用加密算法的区别,从结果来看影响似乎不是很大。并且随着测试次数的增加,我猜测可能是与缓存机制有关,对于同一文件的读写测试,在数值上区别越来越小,甚至还有加密后的速度超过不加密的情况。看起来只要手机不是特别差(好歹Mix2用的也是835呢),文件级加密完全没有问题,而出于安全考虑,我的手机开了文件级加密,而电脑的C盘也开了BitLocker,这样一来即便丢了,也不会造成数据泄露。
-全文完-
【歪门邪道】修复小米MIX2在MIUI EU版上无法开启加密的问题 由 天空 Blond 采用 知识共享 署名 - 非商业性使用 - 相同方式共享 4.0 国际 许可协议进行许可。
本许可协议授权之外的使用权限可以从 https://skyblond.info/about.html 处获得。
小米6 最新 MIUI EU 版本可用。感谢大佬。
支持一下交个朋友
👴哭了,手上的日版Xperia不让解BL
一看就知道是技术大拿。学习了。@(你懂的)