棉花糖加密在技术上如何工作?


14

我只是通过推送更新在Nexus 5上安装了棉花糖。我对加密的工作方式感到困惑。我在计算机加密方面具有很好的技术知识。我想获得有关Android 6的类似知识。

以下是我的工作以及如何感到困惑。恢复出厂设置后,我设置了PIN,然后对设备进行了加密。在启动时,它要求我提供我的PIN码,这是预期的。然后,我删除了PIN,然后重新启动了设备。它在启动时不要求输入任何PIN,但设备仍在设置菜单中报告为已加密。后者使我感到困惑,因为我希望PIN解锁解密密钥。

问题:

  • 在没有PIN的情况下,解密密钥从何而来?我假设它存储在类似于TPM的芯片上,这是正确的吗?如果是这样,是什么阻止了黑客从芯片上请求此密钥?它会检查固件的哈希值吗?还要别的吗?技术细节将不胜感激。
  • 如果使用PIN进行加密,是否将PIN用作访问解密密钥的额外令牌?还是解密过程完全像没有PIN一样工作。

TL; DL回答:

解密密钥通过以下所有方式解锁:

  • PIN(或密码等)或默认密码(如果没有)
  • TEE(硬件支持的签名生成器,使用无法提取的密钥)
  • 盐(易于获取,但可以防止彩虹表攻击)

谢谢。就我所知,即使它适用于棒棒糖,这也是正确的答案。我以为M和L之间是有区别的,因为我不记得能够在L上设置无密码加密,也不能在加密后删除我的PIN。
marcv81 2015年

Answers:


15

我在这里引用《 Android手册》,但是:

注意:

我使用的来源与棉花糖并不直接相关,但与棒棒糖及更高版本有关。

TL:DR

我现在就解决OP的问题。技术细节将在后面介绍。

  1. 默认加密密钥来自硬件源(类似于TPM芯片)和定义为AOSP的预设密码default_passwordcryptfs.c的源文件,见下文。

  2. 是的,不仅是默认密码,而且所有密码都被设置为密钥,并存储在类似TPM的芯片上,称为TEE(“受信任的执行环境”的缩写,更多详细信息,请参见下文)。

  3. 通过UART / JTAG访问设备SoC芯片的黑客可以从技术上访问TEE密钥,或者自定义内核可以将该信息泄漏给黑客。一些阴谋论中的三字母代理机构可能可以与OEM合作,以将这些不安全的内核用于生产设备,但我不会为此而设很多商店。同样,请参见此答案的最后一节以获取更多详细信息。

阻止黑客访问密钥的唯一方法就是要做大量的工作。

  1. 实际上,默认情况下,在Lollipop上及以上(由JellyBean 4.3起可用)对固件(由Google 称为“验证启动”)的哈希(校验和)进行检查(实际上是在Lollipop上及以上)dm-verity。但是,这与加密状态无关。

来源: AOSP安全指南这里

  1. 关于使用自定义密码解密系统所涉及的过程,请参见下文。我仅在此告诉您,密码的创建和使用都涉及用户密码。

总览

首次启动时,设备会创建一个随机生成的128位主密钥,然后使用默认密码和存储的盐对其进行哈希处理。默认密码为:“ default_password”但是,生成的哈希也通过TEE(例如TrustZone)进行签名,TEE使用签名的哈希来加密主密钥。

您可以在Android开放源代码项目cryptfs.c中找到定义的默认密码文件中。

当用户在设备上设置PIN /密码时,仅128位密钥被重新加密和存储。(即,用户PIN /通过/模式更改不会引起对用户数据分区的重新加密。)

使用默认加密启动加密设备

当您启动没有密码的加密设备时,就会发生这种情况。由于Android 5.0设备在首次启动时已加密,因此不应设置密码,因此这是默认的加密状态。

  1. 检测没有密码的加密/数据

检测到Android设备已加密,因为/ data无法挂载,并且其中一个标志encryptableforceencrypt设置之一。

vold设置vold.decrypttrigger_default_encryption,将启动defaultcrypto服务。trigger_default_encryption检查加密类型以查看/ data是否使用密码进行了加密。

  1. 解密/数据

dm-crypt在块设备上创建设备,以便可以使用该设备。

  1. 挂载/数据

vold然后挂载解密的真实/ data分区,然后准备新分区。它将属性设置vold.post_fs_data_done0,然后设置vold.decrypttrigger_post_fs_data。这导致init.rc运行其post-fs-data命令。他们将创建任何必要的目录或链接,然后将其设置vold.post_fs_data_done1

一旦vold在该属性中看到1,就会将该属性设置vold.decrypt为:trigger_restart_framework。这会导致init.rc启动类的服务main再次也在类开始服务late_start为开机以来的第一次。

  1. 启动框架

现在,框架使用解密的/ data引导所有服务,并且系统可以使用了。

启动没有默认加密的加密设备

这是当您启动具有设置密码的加密设备时发生的情况。设备的密码可以是大头针,图案或密码。

  1. 使用密码检测加密的设备

检测到Android设备已加密,因为该标志 ro.crypto.state = "encrypted"

vold设置vold.decrypt为,trigger_restart_min_framework因为/ data使用密码加密。

  1. 挂载tmpfs

init设置五个属性,以保存从/传递给/ data的初始安装选项init.rcvold使用以下属性来设置加密映射:

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)

  1. 启动框架以提示输入密码

框架启动,并看到将其vold.decrypt设置为trigger_restart_min_framework。这告诉框架它正在启动tmpfs /data磁盘上并且需要获取用户密码。

但是,首先,需要确保磁盘已正确加密。它将命令发送cryptfs cryptocompletevoldvold如果加密成功完成,则返回0;如果内部错误,则返回-1;如果加密未成功完成,则返回-2。vold通过在加密元数据中查找CRYPTO_ENCRYPTION_IN_PROGRESS标志。如果已设置,则加密过程被中断,并且设备上没有可用的数据。

如果vold返回错误,则UI应向用户显示一条消息,以重新引导设备并将其恢复出厂设置,并为用户提供一个按此操作的按钮。

  1. 用密码解密数据

一旦cryptfs cryptocomplete成功,该框架显示UI要求磁盘密码。所述UI检查通过发送该命令的密码cryptfs checkpwvold。如果密码正确(这是通过/data在一个临时位置成功安装解密的文件,然后再卸载来确定的),则vold将解密的块设备的名称保存在属性中ro.crypto.fs_crypto_blkdev,并向UI返回状态0。如果密码不正确,它将返回-1。

  1. 停止框架

UI放置了一个加密启动图形,然后使用命令调用vold cryptfs restartvold将属性设置vold.decrypttrigger_reset_main,从而导致init.rc这样做class_reset main。这将停止main该类中的所有服务,从而允许将tmpfs /data其卸载。

  1. 挂载/数据

vold然后挂载解密后的真实/data分区并准备新分区(如果使用“擦除”选项加密了该分区,则该分区可能从未准备过,这在第一个发行版中不支持)。它将属性设置vold.post_fs_data_done0,然后设置vold.decrypttrigger_post_fs_data。这导致init.rc运行它post-fs-data commands。他们将创建任何必要的目录或链接,然后将其设置vold.post_fs_data_done1。一旦在该属性中vold看到1,便将该属性设置vold.decrypttrigger_restart_framework。这将导致init.rc再次启动类服务,main并且late_start自启动以来首次启动类服务。

  1. 开始完整的框架

现在,该框架使用解密的/ data文件系统引导所有服务,并且该系统可以使用。

存储加密密钥

加密的密钥存储在加密元数据中。硬件支持是通过使用受信任的执行环境(TEE)签名功能来实现的。以前,我们使用通过应用scrypt到用户的密码和存储的盐生成的密钥来加密主密钥。

为了使密钥对现成的攻击具有弹性,我们通过使用存储的TEE密钥对生成的密钥进行签名来扩展此算法。然后,通过再次应用,将生成的签名转换为适当的长度密钥scrypt。然后,此密钥用于加密和解密主密钥。要存储此密钥:

  1. 生成随机的16字节磁盘加密密钥(DEK)和16字节盐。
  2. 应用于scrypt用户密码和盐,以生成32字节的中间密钥1(IK1)。
  3. 用零字节填充IK1,以达到硬件绑定私钥(HBK)的大小。具体来说,我们填充为:00 || IK1 || 00..00; 一个零字节,32个IK1字节,223个零字节。
  4. 用HBK对填充的IK1进行签名,以生成256字节的IK2。
  5. 将其scrypt应用于IK2和盐(与第2步相同的盐)以产生32字节的IK3。
  6. IK3的前16个字节用作KEK,后16个字节用作IV。
  7. 使用AES_CBC,密钥KEK和初始化向量IV加密DEK。

那么Android N呢?同事们曾假设加密的Android 7较弱,因为设备的启动未像以前那样受到保护,因此攻击者比以前更容易使用它,您认为这是真的吗?
大卫,

@David超出了此问题的范围,请询问有关Android Nougat的其他问题。
Tamoghna Chowdhury


如何在恢复模式下解密DATA分区?通过init.recovery。<ro.hardware> .rc
Benny

@Benny请问一个适当的问题
Tamoghna Chowdhury
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.