android全磁盘加密
android 全磁盘加密
什么是全磁盘加密?
全磁盘加密是使用一个密钥来为android设备上全部的用户数据加密的过程。一旦设备被加密,全部的用户创建的数据都将会在提交的磁盘之前自己主动加密,在读取之前都会自己主动解密。
- 创建了高速加密,该加密方式只加密在数据分区中使用块设备的数据来避免第一次启动耗费较长时间。只ext4和f2fs文件系统支持高速加密。
- 在首次启动的时候加入forceencrypt标志来加密
- 添加了对模式的支持和没有password的加密
- 添加使用可信执行环境的密钥的硬件支持存储。
注意:升级到Android5.0而且被加密的设备可能会数据恢复出厂后返回一个未加密状态。在首次启动时加密的新的Android 5.0设备不能返回到未加密状态。
Android全磁盘加密基于dm-crypy,他是一个内核特征,工作在块设备层。出于这个原因,加密是和嵌入式多媒体卡和作为块设备的闪存设备一起工作的。在YAFFS文件系统中,加密是不可能工作的,他是直接和NAND闪存芯片工作的。
加密算法是带有CBC和 ESSIV:SHA256的128高级加密标准。主键是通过128位AES通过OpenSSL库被加密的。你必需要使用128位或更大位数的键值。
注意:OEMs可以使用128位或更高位数来加密主键。
在Android5.0的发行版中,有四种加密状态:
- 默认
- PIN
- password
- 模式
在第一次启动的时候。设备创建一个随机生成的128位主键。然后使用默认password和存储的salt进行哈希运算。默认password是”default_password”。
然而,结果散列也需要通过TEE进行签名。他使用一个签名的散列来加密主键。
你可以在Android源代码文件cryptfs.c中找到默认password。
当用户在设备中设置了PIN或者是password。只128位的键被又一次加密和存储。
(用户PIN/password/模式的改变不会造成用户数据又一次加密)。注意管理的设备可能会受到PIN,模式或password的限制。
加密是由init和vold管理的。
init调用vold。vold设置位于init中的属性来触发事件。
系统的其它部分也会依据这些属性来进行工作,比如报告状态,查询password。或者是发生致命错误的时候及时工厂重置。
为了在vold中激活加密特征。系统使用命令行工具vdc
’s cryptfs执行命令:
checkpw
, restart
, enablecrypto
, changepw
, cryptocomplete
, verifypw
,setfield
, getfield
, mountdefaultencrypted
, getpwtype
, getpw
, 和clearpw
.
为了进行加密,解密或清除/data,/data必需要被挂载。然而,为了可以显示用户接口,框架一定要执行而且框架需要/data来执行。为了解决这个难题,在/data中会挂载一个暂时的文件系统。这使得安卓可以提示password,显示进展,或在需要的时候进行数据擦除。在从暂时文件系统到真实的/data文件系统的转换的时候强加了一些限制,系统必需要停止打开暂时文件系统中文件的每个进程,然后在真实的/data文件系统中重新启动这些进程。
为了这样做,全部的服务都必须在这三个组中的一个中:core,main和late_start。
- core:在启动后永远不关闭
- main:在磁盘password输入后关机在重新启动
- late_restart:在/data被解密而且挂载之前不要開始
为了激发这些行为,vold.decrypt属性被设置为各种字符串。为了杀死而且重新启动服务,init命令为:
- class_reset:停止服务。而且同意使用class_start进行重新启动。
- class_start:重新启动服务
- class_stop:停止一个服务,而且加入一个SVC_DISABLED标志。
停止的服务不向class_start做出回应。
对于一个加密的设备来说有四个流。一个设备只加密一次。然后遵循一个正常的启动流。
- 加密一个原先未加密的设备:
- 使用forceencrypt加密一个新的设备:在首次启动的时候强制性加密(在Android L開始)
- 加密一个存在的设备:用户初始化加密(Android K而且更早)
- 启动一个加密设备:
- 启动一个不带password的加密设备:启动一个没有设置password的加密设备(相关的设备运Android 5.0或更新)
- 開始一个带有password的加密设备:启动一个设置password的加密设备。
除了这些流,设备加密/data就会失败。每个流在以下都会详解。
这是一个Android 5.0设备正常的首次启动。
检測到带有
/forceencrypt标志的未加密文件系统
/data没有被加密,可是必需要进行加密。由于
/forceencrypt托付他这样做。
卸载/data
- 開始加密/data
vold.decrypt = "trigger_encryption"
triggersinit.rc
, which will causevold
to encrypt/data
with no password. (None is set because this should be a new device.) - 挂载tmpfs
vold挂载一个暂时文件系统 /data(从ro.crypto.tmpfs_options中使用tmpfs选项)。而且设置属性
vold.encrypt_progress
为0.vold为启动一个加密的系统准备tmpfs /data,而且设置属性vold.decrypt为trigger_restart_min_framework - 提出框架。显示运行进度
由于该设备差点儿没有数据去加密了,进度条也不会显示了,由于加密过程会非常快。
- 当/data被加密之后,卸下框架
vold设置vold.decrypt为 開始
defaultcrypto
服务的trigger_default_encryption。(这个会開始以下的流用于挂载一个默认的加密用户数据)。trigger_default_encryption检查加密类型来查看/data是否是带有password被加密的。由于Android5.0设备在首次启动的时候被加密,应该没有password设置。因此我们解密而且挂载/data。 - 挂载/data
init然后使用从
ro.crypto.tmpfs_options中选出的參数在tmpfs的
RAMDisk 中挂载/data。ro.crypto.tmpfs_options是在init.rc中被设置的。 - 启动框架
设置vold为trigger_restart_framework。他继续常规的启动进程。
这样的情况发生在你加密一个未加密的Android k或更早版本号的设备,该设备被一直到Android L的时候。
注意,这个和在K中使用的流是一样的。
这个进程是用户初始化的。而且在代码中被引用作为”就地加密”。当一个空户选择去加密一个设备的时候,UI确保电量是全然充电状态而且AC适配器被插入。所以有足够的变量来完毕加密进程。
警告:假设设备在完毕加密之前耗尽电量而且关机了,在部分加密状态下会留下文件数据。设备必需要工厂重置,全部的数据都会丢失。
为了使能就地加密,vold開始一个循环来读取真实块设备的每个扇区,然后将他写到加密块设备中。vold在读取和写数据之前。检查扇区是否正在使用。这会使得在差点儿没有数据的新设备上加密会非常快。
设备状态:设置ro.crypto.state = "unencrypted"
而且执行 on nonencrypted
init触发器来继续启动。
- 检查password
UI在passwd是用户锁屏password的地方调用带有命令cryptfs enablecrypto inplace的vold。
- 卸载框架
vold检查错误。假设不能被加密,返回-1。而且在日志中打印原因。
假设可以加密,设置属性
vold.decrypt为
trigger_shutdown_framework。这会使init.rc停止位于类late_start和main中的服务。
- 卸载/data
vold卸载/mnt/sdcard。然后卸载/data。
- 開始加密/data
vold然后设置加密映射。该映射创建一个虚拟加密块设备。该设备映射到真实的块设备上。可是当写入的时候加密每个扇区,当读取的时候解密每个扇区。vold然后创建和编写加密元数据。
- 当加密的时候。挂载tmpfs
vold挂载一个tmpfs /data(从
ro.crypto.tmpfs_options中使用tmpfs选项),而且设置属性vold.encrypt_progress为0.vold为启动一个加密系统准备tmpfs /data,而且设置属性vold.decrypt为trigger_restart_min_framework。 - 提出框架,显示运行进度
trigger_restart_min_framework会使init.rc開始一个服务的main类。
当框架看到vold.encrypt_progress被设置为0,他就会显示运行进度条UI,他每5秒钟查询一下属性然后更新进度条。每次他加密了一部分分区,加密程序就会更新
vold.encrypt_progress。
- 当/data被加密。重新启动
当/data被成功加密了,vold会清除位于元数据中的标志ENCRYPTION_IN_PROGRESS。然后重新启动。
假设某些原因重新启动失败,vold会设置属性
vold.encrypt_progress为
error_reboot_failed
,而且UI应该会展示一个信息询问用户按下button重新启动。这样的情况永远也不期望发生。
这样的情况发生在当你想启动一个没有password的加密设备的时候。由于Android 5.0设备在首次启动的时候被加密,应该没有设置password,因此应该是默认加密状态。
- 检測加密的没有password的/data
检測Android设备已被加密,由于/data不能被挂载,而且标志flags
encryptable
或forceencrypt
之中的一个被设置了。vold设置vold.decrypt为
trigger_default_encryption,他用于启动
defaultcrypto
。trigger_default_encryption
检查加密类型来查看/data有无password加密。 - 解密/data
在块设备中,创建dm-crypt设备。所以设备已经可以使用。
- 挂载/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中的服务。
- 开启框架
如今,框架使用加密的/data启动全部他的服务。而且系统也可以正常使用了。
这样的情况发生在,当你启动一个设置password的加密设备的时候。这个设备的password可以是pin,模式或password。
- 检測带有password的加密设备
检測到Android设备被加密了,由于标志ro.crypto.state = “encrypted”
vold设置vold.decrypt为trigger_restart_min_framework,由于/data是使用password加密的。
- 挂载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-digit hex number preceded by 0x)
- 启动框架以提示输入password
框架启动,然后查看vold.decrypt是否被设置为
trigger_restart_min_framework。
这告诉框架这是在tmpfs /data磁盘中启动的,他需要获取用户password。
首先,他需要确定磁盘是否被正确加密。他发送命令cryptfs cryptocomplete到vold。
假设加密全然成功,则返回0.假设内部错误,返回-1.或者是假设加密没有全然成功返回-2。vold通过查看用于CRYPTO_ENCRYPTION_IN_PROGRESS标志的加密元数据来决定这个。假设被设置了。加密进程被中断了,在设备中没有可用的数据。
假设vold返回一个错误。UI应该向用户展示一个信息来重新启动和工厂重置设备,而且给用户一个button来这样做。
- 解密带有password的数据
一旦cryptfs cryptocomplete成功了。框架就会展示一个UI询问磁盘password。
UI通过向vold发送命令
cryptfs checkpw
来检查password。假设password正确(这是由正确挂载到暂时位置的加密/data决定的,然后卸载塔),vold在属性ro.crypto.fs_crypto_blkdev中保存解密块设备的名称,而且向UI返回状态0.假设password不对。向UI返回-1。 - 停止框架
UI弹出一个加密启动图形。然后使用命令
cryptfs restart
.vold设置属性
vold.decrypt为trigger_reset_main来调用vold,这样会使init.rc
去处理class_reset main。这会在主类中停止全部的服务。这同意tmpfs /data被卸载。 - 挂载/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中的服务。 - 开启全框架
如今,框架就会使用解密/data文件系统启动他全部的服务,而且系统准备投入使用。
一个解密失败的设备可能是以下几个原因。设备使用常规系列步骤開始启动:
- 检測带有password的加密设备
- 挂载tmpfs
- 开启框架提示输入password
可是框架打开之后,设备可能会遇到一些错误:
- password匹配可是不能解密数据
- 用户输入错误password30次
假设这些错误没有解决,提示用户进行工厂清除:
假设vold在加密过程中检測到一个错误,而且假设数据还没有被解密,框架启动了。vold设置属性vold.encrypt_progress为error_not_encrypted。UI提示用户重新启动。而且警告他们加密过程没有開始。假设在框架卸下之后,在进度条开启之前,发生错误了,vold将会重新启动系统。假设重新启动失败,他会设置
vold.encrypt_progress为error_shutting_down,而且返回-1。可是将不会有不论什么事情捕获错误。这是不希望发生的。
假设vold在加密过程中检測到一个错误。他会设置 vold.encrypt_progress为
error_partially_encrypted,而且返回-1.UI应该会展示一个信息框说加密失败,而且提供一个button提示用户恢复出厂重置设备。
加密键值存储在加密元数据中。
硬件支持是通过使用可信环境签名实现的。在曾经,我们通过向用户password和存储salt应用scrypt来加密主键。为了使键抵抗攻击,我们通过使用一个存储的TEE键签名一个组合键值来继承他的算法。组合签名通过一个scrypt的应用编程一个合适的密钥长度。这个密钥被使用去加密和解密主密钥。以下是存储这个密钥的过程:
- 生成随机16位的磁盘加密密钥(DEK)和16为salt。
- 向用户password应用scrypt和salt来生成32位的中间密钥1(IK1)。
- 使用0填充IK1到硬件绑定私钥(HBK)的大小。
特别的。我们填充为: 00 || IK1 || 00..00;一个0位:32 IK1 bytes, 223 zero bytes.
- 签名带有HBK的IK1来生成256位的IK2
- 将scrypt应用到IK2和salt中来生成32为IK3
- 使用IK3的前16位作为KEK,后16位作为IV
- 加密带有AES_CBS,带有密钥KEK的DEK,而且初始化向量IV
当用户选择在设置中改动或移除password的时候,UI发送命令cryptfs changepw到vold中,vold又一次加密带有新password的磁盘主密钥。
加密属性
vold和init通过设置属性相互交流。
以下一些用于加密的可用属性。
Vold属性
属性 | 描写叙述 |
---|---|
vold.decrypt trigger_encryption |
加密没有password的设备 |
vold.decrypt trigger_default_encryption |
检查设备是否是在没有password的情况下加密的。假设是,解密而且挂载他。假设不是,设置vold.decrypt为trigger_restart_min_framework. |
vold.decrypt trigger_reset_main |
由vold设置关闭UI来询问磁盘password |
vold.decrypt trigger_post_fs_data |
由vold设置来准备带有必要文件夹的/data |
vold.decrypt trigger_restart_framework |
由vold设置来启动实际框架和全部服务 |
vold.decrypt trigger_shutdown_framework |
由vold设置关闭总体框架来启动加密 |
vold.decrypt trigger_restart_min_framework |
由vold设置開始进度条来加密或者是提示用户输入password,依赖于ro.crypto.state的值 |
vold.encrypt_progress |
当框架启动的时候,假设这个属性被设置,进入进度条模式 |
vold.encrypt_progress 0 to 100 |
进度条应该会展示百分值集合。 |
vold.encrypt_progress error_partially_encrypted |
进度条应该展示一个加密失败提示信息。而且给用户一个选项来工厂重置设备。 |
vold.encrypt_progress error_reboot_failed |
进度条应该显示一个信息说加密完毕,而且给用户提供一个button提示用户重新启动设备。
这个错误我们不期望发生。 |
vold.encrypt_progress error_not_encrypted |
进度条应该展示一个信息框说发生了一个错误,没有数据被加密。而且给用户一个button提示用户重新启动系统。 |
vold.encrypt_progress error_shutting_down |
进度条没有执行,所以不清楚谁回应这个错误。
他应该不会发生。 |
vold.post_fs_data_done 0 |
在设置vold.decrypt到trigger_post_fs_data之前 由vold设置 |
vold.post_fs_data_done 1 |
在完毕任务post-fs-data之后由init.rc设置 |
init属性
属性 | 描写叙述 |
---|---|
ro.crypto.fs_crypto_blkdev |
由vold命令checkpw 设置用于后面被vold命令restart使用。
|
ro.crypto.state unencrypted |
由init设置说这个系统正在用未加密的/data ro.crypto.state encrypted执行。
由init设置说这个系统正在用加密的/data执行 |
|
在他尝试去挂载带有从 init.rc . vold中传来的參数的/data的时候。 这五个属性由init设置来设置加密映射 |
ro.crypto.tmpfs_options |
当挂载tmpfs /data文件系统的时候。由init.rc使用init应该使用的參数来设置。 |
Init行为
on post-fs-data
on nonencrypted
on property:vold.decrypt=trigger_reset_main
on property:vold.decrypt=trigger_post_fs_data
on property:vold.decrypt=trigger_restart_min_framework
on property:vold.decrypt=trigger_restart_framework
on property:vold.decrypt=trigger_shutdown_framework
on property:vold.decrypt=trigger_encryption
on property:vold.decrypt=trigger_default_encryption
android全磁盘加密的更多相关文章
- Android 全屏显示
Android全屏显示: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInst ...
- Android开发周报:Android L默认加密用户数据
Android开发周报:Android L默认加密用户数据 新闻 <iCloud前车之鉴,Android L默认开启加密功能>:iCloud 艳照风波再起,第二波女星照片流出,大量女星的裸 ...
- wemall app商城源码android开发MD5加密工具类
wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享android开发MD5加密工具类主要代码,供 ...
- linux 磁盘加密和tpm搭配使用1
一.基本名称,容易混淆 1.dm-crypt是linux的2.6内核开始集成的一种磁盘加密功能.十几年来,连sche调度算法都被改了N次,但dm-crypt一直稳定在内核中,稳定性还是很好的. 2.c ...
- 小小知识点(一)——利用电脑自带的BitLocker对磁盘加密
1.利用电脑自带的BitLocker可以对固定的或移动的磁盘加密 网上有很多的使用方法步骤,可参考百度经验:https://jingyan.baidu.com/article/636f38bb4fac ...
- android 对称加密,非对称加密 android 常见的加密
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha android 常见的加密 ======== 不可逆加密:md5,sha1 可逆的加密中 ...
- windows 磁盘加密
windows 磁盘加密 CreateTime--2018年4月25日18:37:45 Author:Marydon 以win10为例 选中磁盘-->你会发现上面的管理BitLocker是置 ...
- openstack havana块存储Cinder磁盘加密方法研究
http://blog.csdn.net/cloudresearch/article/details/19092219 在openstack havana的release note中有如下介绍“Att ...
- android全屏去掉title栏的多种实现方法
android全屏去掉title栏的多种实现方法 作者: 字体:[增加 减小] 类型:转载 时间:2013-02-18我要评论 android全屏去掉title栏包括以下几个部分:实现应用中的所有ac ...
随机推荐
- 源码高速定位工具-qwandry
https://github.com/adamsanderson/qwandry qwandry 能高速定位到我们须要找到 库文件, 项目 的工具. Ruby中实现高速定位的方法有好多种.我知道的有三 ...
- (素数求解)I - Dirichlet's Theorem on Arithmetic Progressions(1.5.5)
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit cid=1006#sta ...
- 编写函数int count_number_string(char str[])和函数int maxnum_string(char str[])
题目如图: 这里不再赘述 代码: //字符串中统计与查询 //杨鑫 #include <stdio.h> #include <stdlib.h> #include <st ...
- 英语发音规则---X字母
英语发音规则---X字母 一.总结 一句话总结: 1.x位于词尾或音节尾部,读/ks/? box /bɒks/ n.盒; 箱状物 fix /fɪks/ vt.固定 fox /fɒks/ n.狐; 狐狸 ...
- 使用CNN做电影评论的负面检测——本质上感觉和ngram或者LSTM同,因为CNN里图像检测卷积一般是3x3,而文本分类的话是直接是一维的3、4、5
代码如下: from __future__ import division, print_function, absolute_import import tensorflow as tf impor ...
- 知网下载pdf文件的方法
title: 知网下载pdf文件的方法 toc: false date: 2018-11-02 17:54:43 categories: methods tags: 知网 平时我们使用的是国内版的知网 ...
- 服务端 | Nodejs 学习笔记(一)
Node.js 前言: 2009年面世 nodejs.org 官网 https://www.npmjs.com/ 模块社区 github.com 仓库 stackoverflow.com 问答社区 ...
- tp5控制器调用,方法调用
<?php //命名空间 namespace app\index\controller; use app\admin\controller\Deer; class User{ public ...
- 织梦Fatal error: Call to a member function GetInnerText()
问题:织梦修改或者添加了自定义表单后在后台修改文章的时候出现如下错误:Fatal error: Call to a member function GetInnerText() on a non-ob ...
- ZBrush各种拓展功能的简单介绍
ZBrush的一些拓展功能中,比较突出的有2.5D的绘画功能,这个功能可以让ZBrush®从一个三维的雕塑软件转变成为一个二维的绘画软件.你完全可以使用ZBrush®来绘制自己喜欢的平面插画,还可以是 ...