如果创建新的 LUKS 设备,则可以指定选项-hash
和-iter-time
。
例如这样:
sudo cryptsetup luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --iter-time 2100 --hash sha512 /dev/loop0
来自 cryptsetup 的联机帮助页:
--哈希,-h
对于创建操作指定用于密码散列的散列。
对于 luksFormat 操作指定 LUKS 密钥设置方案和卷密钥摘要中使用的哈希。
由于第一句话,我天真地假设哈希值的使用方式与标准 Linux 系统中类似,其中哈希值是由指定算法创建的(例如sha512
)。为了让拥有哈希值并想要尝试字典攻击的攻击者变得更加困难,哈希值被加盐并且算法被迭代 n 次以延长计算时间。在这种情况下,has 值存储在 中/etc/shadow
。如果用户登录,则会计算哈希值并将其与/etc/shadows
文件中的值进行比较。如果相等,则允许用户登录。以类似的方式,拥有该文件的攻击者/etc/shadow
(从那里他也知道盐值)可以根据字典中的单词计算哈希值,并将其与文件中的值进行比较,/etc/shadow
直到某些字符串匹配为止。
如果 LUKS 中的哈希以类似的方式使用,我假设它必须存储在某个地方(例如在分区标头中),并且如果攻击者出于某种原因可以访问分区标头(或存储它的文件),他可以用与上面类似的方法来找出密码。这让我想到了如何获取哈希值的问题:如何提取 LUKS 设备的哈希值?
想想LUKS系统可能是如何工作的,我猜它不是这样使用的。相反,我认为密码只是用于加密密钥(并且没有散列存储在任何地方),它被加密存储在标头中。但在 LUKS 手册页中我没有找到任何提示,即使用哪种加密算法进行密钥加密以及如何更改它。 (这些选项--cipher aes-cbc-essiv:sha256 --key-size 256
指的是用于加密分区而不是密钥的实际算法)。这对我来说表明这种理解也是不正确的。
那么,这一切到底是如何运作的以及上述哈希的作用是什么?如果有人能澄清我上面的误解(也许有一些参考资料),那就太好了。
答案1
LUKS 格式有多个密钥槽,每个密钥槽都可以包含用于数据加密的加密主密钥。该主密钥使用从您的密码派生的另一个密钥进行加密。
使用 plainhash_function(passphrase)
生成密钥会很愚蠢,因为可以快速计算诸如 sha1 之类的哈希值(SHA-1 是苹果算法,用于验证消息,不是用作普通密码)。
对于基于密码的数据加密,您希望该函数速度较慢以阻止暴力攻击。为此,使用 PBKDF2(基于密码的密钥派生函数)(请参阅关于这个 Sec.SE 问题动机和其他示例)。
derivedKey = PBKDF2(hash_function, passphrase, salt, iterations, derivedKeyLen)
我安装的 hash_function 是 sha1,如下所示cryptsetup --help
:
Default compiled-in key and passphrase parameters:
Maximum keyfile size: 8192kB, Maximum interactive passphrase length 512 (characters)
Default PBKDF2 iteration time for LUKS: 1000 (ms)
Default compiled-in device cipher parameters:
loop-AES: aes, Key 256 bits
plain: aes-cbc-essiv:sha256, Key: 256 bits, Password hashing: ripemd160
LUKS1: aes-xts-plain64, Key: 256 bits, LUKS header hashing: sha1, RNG: /dev/urandom
导出的密钥长度取决于用于数据加密的密码。迭代次数取决于您的处理器速度。
这些详细信息可以在 cryptsetup 的手册页中找到(pbkdf2 应该响一下)。有关其他安全详细信息,请参阅密码设置常见问题解答。
答案2
你是对的,存储加密凭据和存储身份验证凭据是两个不同的问题。
当用户登录时,操作系统需要有其密码的参考副本,以便与用户输入的密码进行比较。如果输入的密码与参考密码相同,则认证成功。为了使密码恢复变得困难,系统不存储密码,而是存储散列(一个缓慢的加盐哈希,使暴力尝试猜测密码变得更加困难)。
加密的工作方式有所不同。目的是防止有权访问存储的攻击者,因此不能仅从设备上存储的内容中提取加密密钥。因此,密钥不存储在设备上,而是根据存储在设备上的信息与用户提供的信息相结合来构造。通常,密钥是根据设备上存储的盐与用户提供的密码结合生成的。同样,为了减慢暴力尝试,组合这些值的过程必须很慢,并且除了用户密码之外,该过程还使用每个设备的值(盐),这样使用相同的密码就不会导致到同一个键。
事实证明,从密码学的角度来看,慢速密码哈希和慢速密钥导出函数是同一个问题,称为琴键拉伸。卢克斯用途PBKDF2,事实上的标准密钥扩展函数之一(尽管密码破解方面的技术进步使得 bcrypt 或 scrypt 更可取)。现代 UNIX 系统使用类似的机制密码散列(“MD5”或“SHA-512”实际上是迭代的,结构与PBKDF2类似)
如果用户提供的密码不正确,则数据解密将返回垃圾。
与大多数其他加密机制一样,LUKS 不使用从密码派生的密钥作为数据的加密密钥。相反,数据加密密钥是在创建设备时随机生成的,但不直接存储。 LUKS 存储使用每个密码派生密钥加密的该密钥的副本。在 LUKS 术语中,每个密码派生密钥在卷标头中占据一个位置;每个插槽对应一个密码。您可以阅读TKS1纸有关两层加密方案的详细信息。