分享好友 最新资讯首页 最新资讯分类 切换频道
Android加密之全盘加密手机加密「Android加密之全盘加密」
2025-05-12 12:23

前言

Android 的安全性问题一直备受关注,Google 在 Android 系统的安全方面也是一直没有停止过更新,努力做到更加安全的手机移动操作系统。
在 Android 的安全性方面,有很多模块

  1. 内核安全性
  2. 应用安全性
  3. 应用签名
  4. 身份验证
  5. Trusty TEE
  6. SELinux
  7. 加密 

 

等等其中,加密又分全盘加密(Android 4.4 引入)和文件级加密(Android 7.0 引入,本文将论述加密中的全盘加密的基本知识。全盘加密在 Android 4.4 中引入,在 Android 5.0 中做了比较大的更新。

本文部分片段摘自 Android 官网,融合笔者的个人理解和知识。

 

什么是全盘加密

全盘加密是使用已加密的密钥对 Android 设备上的所有用户数据进行编码的过程。设备经过加密后,所有由用户创建的数据在写入磁盘之前都会自动加密,并且所有读取操作都会在将数据返回给调用进程之前自动解密数据。
Android 5.0 中又引入了以下新功能

  • 创建了快速加密方式,这种加密方式只会对数据分区中已使用的分块进行加密,以免首次启动用时过长。目前只有 EXT4 和 F2FS 文件系统支持快速加密。
  • 添加了 forceencrypt fstab 标记,以便在首次启动时进行加密。
  • 添加了对解锁图案和无密码加密的支持。
  • 添加了由硬件支持的加密密钥存储空间,该空间使用可信执行环境(TEE,例如 TrustZone)的签名功能。

 

全盘加密运作方式

Android 全盘加密基于在块设备层运行的内核功能 dm-crypt。因此,这种加密方式适用于以块设备的形式呈现给内核的嵌入式多媒体卡 (eMMC) 和类似闪存设备。YAFFS 会直接与原始 NAND 闪存芯片交互,无法进行全盘加密。全盘加密采用的是 128 位高级加密标准 (AES) 算法(搭配密码块链接 (CBC) 和 ESSIV:SHA256)。对主密钥进行加密时使用的是 128 位 AES 算法,并会调用 OpenSSL 库。对于该密钥,您必须使用 128 位或更多位(可以选择 256 位)。
Android 5.0 版中有以下 4 种加密状态

  • 默认
  • PIN 码
  • 密码
  • 解锁图案

首次启动时,设备会创建一个随机生成的 128 位主密钥,然后会使用默认密码和存储的盐对其进行哈希处理。默认密码是“default_password”。不过,设备还会通过 TEE(例如 TrustZone)为生成的哈希签名。TEE 会使用相应签名的哈希来加密主密钥。
您可以在 Android 开放源代码项目 cryptfs.c 文件中找到定义的默认密码。
当用户在设备上设置 PIN 码/通行码或密码时,只有 128 位的密钥会被重新加密并存储起来(也就是说,更改用户 PIN 码/通行码/解锁图案不会导致重新加密用户数据)。请注意,受管理的设备可能受 PIN 码、解锁图案或密码限制。
加密操作由 init 和 vold 管理。 init 负责调用 vold,然后 vold 会设置相关属性以触发 init 中的事件。系统的其他部分也会查看这些属性以执行各项任务,例如报告状态、提示输入密码,或有严重错误发生时提示恢复出厂设置。为了调用 vold 中的加密功能,系统会使用命令行工具 vdc 的 cryptfs 命令:checkpw、restart、enablecrypto、changepw、cryptocomplete、verifypw、setfield、getfield、mountdefaultencrypted、getpwtype、getpw 以及 clearpw。
要加密、解密或清空 /data,/data 不得处于装载状态。但要显示任何界面,框架都必须启动,而框架需要 /data 才能运行。为了解决这一冲突,/data 上会装载一个临时文件系统。通过该文件系统,Android 可以提示输入密码、显示进度或根据需要建议清除数据。不过,该文件系统会带来以下限制:要从临时文件系统切换到实际的 /data 文件系统,系统必须停止临时文件系统中打开了文件的所有进程,并在实际的 /data 文件系统中重启这些进程。为此,所有服务都必须位于以下其中一个组内:core、main 和 late_start

  • core:启动后一直不会关闭。
  • main:关闭,然后在用户输入磁盘密码后会重启。
  • late_start:在 /data 未解密并装载之前,一直不会启动。

为了触发这些操作,vold.decrypt 属性会被设为多种字符串。要结束和重启服务,请使用以下 init 命令

  • class_reset:停止相应服务,但允许通过 class_start 重启该服务。
  • class_start:重启相应服务。
  • class_stop:停止相应服务并添加 SVC_DISABLED 标记。被停止的服务不会对。
  • class_start 做出响应。

 

加密流程和启动流程

使用 forceencrypt 加密新设备

这是 Android 5.0 设备首次启动时的常规流程。
1、检测带有 forceencrypt 标记的未加密文件系统
/data 未加密,但需要加密,因为 forceencrypt 强制要求进行此项加密。卸载 /data。

2、开始加密 /data
vold.decrypt = “trigger_encryption” 会触发 init.rc,从而使 vold 对 /data 进行无密码加密。(因为这应该是新设备,还没有设置密码。

3、装载 tmpfs
vold 会装载一个 tmpfs /data(使用 ro.crypto.tmpfs_options 中的 tmpfs 选项,并会将 vold.encrypt_progress 属性设为 0。 vold 会准备 tmpfs /data 以便启动已加密的系统,并会将 vold.decrypt 属性设为 trigger_restart_min_framework
4、启动框架以显示进度
由于设备上几乎没有要加密的数据,加密过程很快就会完成,因此实际上通常并不会显示进度条。如需关于进度界面的更多详细信息,请参阅加密现有设备。
5、/data 加密后,关闭框架
vold 会将 vold.decrypt 设为 trigger_default_encryption,这会启动 defaultcrypto 服务。(这会启动以下流程来装载默认的已加密用户数据。)trigger_default_encryption 会检查加密类型,以了解 /data 加密是否使用了密码。由于 Android 5.0 设备是在首次启动时加密,应该没有设置任何密码,因此我们要解密并装载 /data。
6、装载 /data
接下来,init 会使用从 ro.crypto.tmpfs_options(在 init.rc 中设置)中选取的参数在 tmpfs RAMDisk 中装载 /data
7、启动框架
将 vold 设为 trigger_restart_framework,这会继续常规启动过程。
 

启动未进行默认加密的已加密设备

当您启动设有密码的已加密设备时,则会发生该流程。设备的密码可以是 PIN 码、解锁图案或密码。
1、检测设有密码的已加密设备
会发现 Android 设备已加密,因为设置了 ro.crypto.state = “encrypted” 标记
由于 /data 是使用密码加密的,因此 vold 会将 vold.decrypt 设为 trigger_restart_min_framework。

2、装载 tmpfs
init 会设置 5 个属性,以保存为 /data(包含从 init.rc 传入的参数)提供的初始装载选项。 vold 会使用这些属性来设置加密映射: 
ro.crypto.fs_type 
ro.crypto.fs_real_blkdev 
ro.crypto.fs_mnt_point 
ro.crypto.fs_options 
ro.crypto.fs_flags (ASCII 码 8 位十六进制数字,以 0x 开头

3、启动框架以提示输入密码
框架会启动并看到 vold.decrypt 已设为 trigger_restart_min_framework。这让框架知道自己是在 tmpfs /data 磁盘中启动的,并且需要获取用户密码。

不过,它首先需要确认磁盘是否已经过适当加密。它会向 vold 发送 cryptfs cryptocomplete 命令。 如果加密已成功完成,vold 会返回 0;如果发生内部错误,则会返回 -1;如果加密未成功完成,则会返回 -2。vold 通过查看 CRYPTO_ENCRYPTION_IN_PROGRESS 标记的加密元数据来确定应返回的值。如果设置了此标记,则表示加密过程中断了,并且设备上没有可用的数据。如果 vold 返回错误,界面中应显示一条消息,提示用户重新启动设备并将其恢复出厂设置,并且界面中应为用户提供一个用于执行该操作的按钮。

4、通过密码解密数据
cryptfs cryptocomplete 成功后,框架会显示一个界面,提示用户输入磁盘密码。界面会向 vold 发送 cryptfs checkpw 命令来检查用户输入的密码。如果密码正确(通过以下方式判定:在临时位置成功装载已解密的 /data,然后将其卸载,vold 会将已解密块设备的名称保存在 ro.crypto.fs_crypto_blkdev 属性中,并向界面返回状态 0。如果密码不正确,则向界面返回 -1。

5、停止框架
界面会显示加密启动图形,然后使用 cryptfs restart 命令调用 vold。vold 会将 vold.decrypt 属性设为 trigger_reset_main,这会使 init.rc 执行 class_reset main 命令。此命令会停止 main 类中的所有服务,以便卸载 tmpfs /data。

6、装载 /data
然后,vold 会装载已解密的实际 /data 分区,并准备新的分区(如果加密时采用了首次发布不支持的数据清除选项,则可能永远无法准备就绪)。它会将 vold.post_fs_data_done 属性设为 0,接着将 vold.decrypt 设为 trigger_post_fs_data。这会使 init.rc 运行其 post-fs-data 命令。这些命令会创建所有必要的目录或链接,然后将 vold.post_fs_data_done 设为 1。当 vold 看到该属性中的 1 时,会将 vold.decrypt 属性设为 trigger_restart_framework。这会使 init.rc 再次启动 main 类中的服务,并启动 late_start 类中的服务(这是设备启动后首次启动这些服务)。

7、启动整个框架
现在,框架会使用已解密的 /data 文件系统启动其所有服务,接下来系统就可以使用了。

 

 

代码解读

结合上章节的流程,下面用代码来解析启动未进行默认加密的已加密设备这个流程。

这个配置定义在 device/lge/bullhead/fstab_fbe.bullhead 文件中。
如上面的代码,在 /data 的末尾加上 fileencryption,便会进行全盘加密。

 

步骤1:检测设有密码的已加密设备

这个方法定义在文件 system/core/init/builtins.cpp 中。

 

这个服务定义在文件 system/vold/vdc.rc 中。

 

这个方法定义在文件 vold/CryptCommandListener.cpp 中。

 

这个方法定义在文件 system/vold/cryptfs.c 中。

 

这个服务定义在服务 system/core/rootdir/init.rc 中。

class_start main 可知重启 main 类别的服务。main 类别的服务包括:

会重启 zygote。

 

步骤2:装载 tmpfs

Zygote 启动后,会 fork() system_process 进程,就是运行 SystemServer 代码了。但是 system_process 的运行需要正常的用户空间(/data,所以,需要临时挂载 tmpfs 分区,这个分区是在内存里分配的临时空间。

这个方法定义在文件 system/vold/CommandListener.cpp 中。

 

这个方法定义在文件 system/core/fs_mgr/fs_mgr.c 中。

 

 

步骤3:启动框架以提示输入密码

这个方法定义在文件frameworks/base/services/java/com/android/server/SystemServer.java 中。

 

这个方法定义在文件 frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java 中

 

这个方法定义在文件 frameworks/base/core/java/android/content/pm/PackageParser.java 中。

安卓中定义为 coreApp 的应用有

Framework-res.apk 的 manifest 配置文件如下

 

 

步骤4:通过密码解密数据

这个过程不再阐述。

 

步骤5:停止框架

这个 setion 定义在文件 system/core/rootdir/init.rc 中。

 

步骤6:装载 /data

这个方法定义在文件 system/core/init/builtins.cpp 中。

 

这个 setion 定义在文件 system/vold/vdc.rc 中。

 

这个 setion 定义在文件 system/vold/vdc.rc 中。

 

这个方法定义在文件 system/vold/CryptCommandListener.cpp 中。


int cryptfs_enable(char *howarg, int type, char *passwd, int no_ui)

这个方法定义在文件 system/vold/CryptCommandListener.cpp 中。

 

这个方法定义在文件 system/vold/cryptfs.c 中。

 

这个方法定义在文件 system/vold/cryptfs.c 中。

 

这个方法定义在文件 system/vold/cryptfs.c 中。

 

这个 setion 定义在文件 system/core/rootdir/init.rc 中。

 

这个 setion 定义在文件 system/core/rootdir/init.rc 中。

 

这个方法定义在文件 system/vold/cryptfs.c 中。

 

 

步骤7:启动整个框架

vold.decrypt = trigger_restart_framework, framework 就可以正常启动了。

 

加密属性

vold 和 init 之间通过设置属性进行通信。下面列出了可用的加密属性。

 

vold属性

 

init 属性

 

init 操作

 

 


Android 全盘加密分析到此为止。

参考 https://source.android.com/security/encryption/full-disk

转载:http://blog.csdn.net/myfriend0/article/details/76615114

 

 

最新文章
小米 MIX 2S 体验:它是目前最全面的小米手机小米手机2s「小米 MIX 2S 体验:它是目前最全面的小米手机」
距离小米 MIX 2 发布只有半年时间,对于一款旗舰机型来说,它的迭代时间未免有些短。而在我们上手体验后,可以在开篇就给出结论
Android加密之全盘加密手机加密「Android加密之全盘加密」
前言 Android 的安全性问题一直备受关注,Google 在 Android 系统的安全方面也是一直没有停止过更新,努力做到更加
突然爆火!涨停!暴增940%
公开数据显示,截至北京时间周二上午,DHgate(敦煌网)已一跃成为了美区App Store排名第二的免费iPhone应用程序,仅次于ChatGPT
摩托罗拉手机驱动android手机驱动「摩托罗拉手机驱动」
摩托罗拉手机驱动是专为摩托罗拉手机打造的驱动,通过它,用户可以轻松地将手机与电脑连接起来,进行各种文件传输,绝对是您生活
《浪姐6》叶童怼房琪:你怀疑我的精力,我觉得你有问题
人气选秀节目《乘风2025》(又称《浪姐6》)节目开播以来,叶童、曹颖、王珞丹、侯佩岑、卡琳娜等参赛艺人频频登上热搜榜,为节
热门赛道 | 储能变流器,能源转型的智能心脏
行业定义储能变流器(PCS, Power Conversion System)是储能系统的核心设备,承担电能双向转换的关键角色:在充电时,将电网或新
原创手机有没有必要经常更新系统?多亏维修师傅说出了真相,涨知识手机系统更新有必要吗「原创手机有没有必要经常更新系统?多亏维修师傅说出了真相,涨知识」
手机到底有没有必要经常去更新系统?相信很多朋友都还不清楚,但是我们在使用手机的时候,却经常遇到这个问题,因为手机总是动不
方光华来眉调研 充分发挥桥梁纽带和服务助手作用 奋力推动民营经济高质量发展
4月13日,全国工商联副主席方光华来眉山调研。市委副书记、市长王斌达陪同。在东坡区太和镇永丰村,方光华一行与当地负责人亲切
手机游戏盒子排行榜前十 2022游戏盒子排行榜第一名手机游戏盒子「手机游戏盒子排行榜前十 2022游戏盒子排行榜第一名」
手机游戏盒子排行榜前十名有哪些推荐?有很多的小伙伴都会在手机中下载各种好玩的游戏资源,但是应用商店中的游戏非常的少,各种
A股短期的“筹码底”已见到?投资主线有哪些?十大券商策略来了
财联社4月13日讯(编辑 若宇)十大券商最新策略观点新鲜出炉,具体如下::A股短期的“筹码底”已见到 4月-5月可能以科技主题型
推荐文章