存储加密后如何更改用户密码?(在 OS X、Android 上)

信息安全 加密 密码 安卓 磁盘加密 苹果系统
2021-08-13 04:12:41

在 OS X ( FileVault ) 和 Android上有内置的加密存储功能。

在 OS X 上:要启用加密,当前用户必须拥有受密码保护的帐户。启用加密后,会生成恢复密钥(类似于HHWj-Y8DK-ODO4-BQEN-FQ4V-M4O8)。加密完成后(很可能在此之前也是如此)用户可以更改他的密码,而无需重新加密存储。

在 Android 上:用户需要将锁屏保护设置为 pin 或密码。存储加密完成后(同样,也可能在此之前),用户可以更改密码,甚至可以从密码切换到密码,反之亦然。

现在让我感到困惑的是:我的理解是,当存储被加密时,它是使用当前用户密码完成的(有点像加密档案),如果密码被更改 - 整个存储必须重新加密。这种(显然是不正确的)理解使我想到以下问题:

  1. 然后基于什么“密钥”(因为它不是密码本身)加密呢?
    • 对于 OS X,我猜,它是恢复密钥,但它是如何连接到用户密码的呢?
  2. 如果密码不是加密的基础,为什么要在加密存储之前设置一个?
  3. 更改密码后如何保持解密存储的能力(无需重新加密)?
2个回答

在较高级别上,磁盘加密是使用数据加密密钥 (DEK) 和密钥加密密钥 (KEK) 实现的。DEK 是随机生成的,用于加密驱动器,KEK 是使用 PBKDF2 或 Argon2 等 KDF 从用户密码导出的,然后用于加密 DEK。

更改密码时,只需使用从新密码派生的新 KEK 对 DEK 进行加密。

可能禁止在没有密码的情况下进行加密,以避免产生错误的安全感。这有点像锁上你的门,但把钥匙留在锁里。

当然,如果您更改密码是因为您相信有人知道了密码,并且该人也可以访问加密设备,那么他们可能存储了 DEK 的副本。在这种情况下,可能需要重新加密整个驱动器,尽管这样做可能需要一些时间。

我完全同意 AndrolGenhald 的高级回答。如果您对 Android 存储加密实现的补充性低级演练感兴趣:

Android 可以进行基于文件的加密 (FBE) 和全盘加密 (FDE),其中“disc”指的是 /data 分区。我将重点介绍 FDE 来说明原理。设置由卷守护程序 (Vold) 完成,特别是在system/vold/cryptfs.cpp中。

  • cryptfs_enable_internal(int crypt_type, const char* passwd, ...)启动存储加密,crypt_type指定是否使用 pin 或密码(以确定在解锁屏幕上显示哪个键盘)并passwd提供实际用户 pin/密码。它将设置一个页脚crypt_ftr以存储在加密分区中,然后调用 create_encrypted_random_key以填充crypt_ftr.

    • create_encrypted_random_key生成一个随机主密钥和一个随机盐并将它们传递给encrypt_master_key.
    • encrypt_master_key使用密钥派生函数(例如 scrypt),它将盐和用户密码/密码作为输入,并确定性地派生一个中间密钥。然后使用 AES-128-CBC 使用中间密钥对主密钥进行加密。加密的主密钥和盐存储在 中crypt_ftr,但不存储用户密码/密码。
    • 回到cryptfs_enable_internalcrypt_ftr被写入光盘。dm-crypt然后使用解密的主密钥触发通过 Linux 的实际存储加密。
  • cryptfs_check_passwd(const char* passwd)通过回溯上述步骤开始存储解密,获取解密后的主密钥。crypt_ftr必须从光盘中读取,其中包含加密的主密钥和盐用户提供的 pin/密码和 salt 被输入到密钥派生函数中。这会产生一个可以解密主密钥的中间密钥(其中大部分发生在 中decrypt_master_key_aux)。

  • cryptfs_changepw(int crypt_type, const char* newpw)处理更改用户密码/密码。它不会生成新的主密钥,它只是通过encrypt_master_key使用新的用户密码/密码来加密现有的主密钥。

根据这些信息,您的问题的答案将是:

  1. 随机生成的主密钥用于实际的存储加密。

  2. 我们需要一个用户密码/密码来加密主密钥。因此,稍后需要用户密码/密码来检索用于解密存储的主密钥。

  3. 更改用户密码/密码不会更改主密钥,只会更改主密钥的加密。