我正在调试 cryptsetup 的一个奇怪行为:
假设文件中存储了正确的密码pw
。我希望现在--test-passphrase
如果它作为标准输入传递,它总是会成功(即不打印输出)。但事实证明它随机失败:
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
No key available with this passphrase.
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
No key available with this passphrase.
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
No key available with this passphrase.
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
No key available with this passphrase.
我注意到了,因为我在引导时(在 GRUB 中)经常多次未能解锁我的分区。首先,我以为我打错了,但现在我觉得这可能是 cryptsetup 中的错误。即使我正在复制粘贴正确的密码,我也无法在以后始终如一地解锁它(不是在 GRUB 中)。
请注意,当我通过这种(主要是等效的)方式传递它时,它也有所不同:
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
在这里,除了一次尝试外,其他所有尝试都失败了。而另一种方法更容易成功。这种行为对我来说是可重现的:它总是更频繁地失败。
# cryptsetup --version
cryptsetup 2.6.1 flags: UDEV BLKID KEYRING KERNEL_CAPI
# cryptsetup luksDump /dev/nvme0n1p2
LUKS header information
Version: 2
Epoch: 5
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID: 2372e472-ef96-428f-b971-f68fb0c35b63
Label: (no label)
Subsystem: (no subsystem)
Flags: (no flags)
Data segments:
0: crypt
offset: 16777216 [bytes]
length: (whole device)
cipher: aes-xts-plain64
sector: 512 [bytes]
Keyslots:
0: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2id
Time cost: 13
Memory: 1048576
Threads: 4
Salt: ea b0 88 ...
f3 f9 72 ...
AF stripes: 4000
AF hash: sha256
Area offset:32768 [bytes]
Area length:258048 [bytes]
Digest ID: 0
Tokens:
Digests:
0: pbkdf2
Hash: sha256
Iterations: 334367
Salt: f0 ac 44 ...
f3 6f d5 ...
Digest: cd a8 ...
23 2a ...
$ uname -a
Linux amd12 6.3.2-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 11 May 2023 16:40:42 +0000 x86_64 GNU/Linux
(OS: Arch Linux)
最终,我总能解锁,但我需要多次尝试,这很烦人。看起来验证码或读取输入的机制是不稳定的。
我想知道这是否是一个已知问题(尽管我还没有发现任何相关问题)?如果没有,有没有办法调试?不幸的是,我没有看到获得任何视觉反馈的选项(我认为,泄露密码长度被认为是一个安全漏洞)。
更新:刚刚意识到有一个--debug
选项。尽管成功和失败运行的输出在计算发生之前是相同的。调试日志中的所有标头和校验和都相同。
此外,它显示了与 Linux Mint Live CD 上的 cryptsetup 2.4.3 相同的行为。
@frostschutz 是正确的。事实证明,我机器上的内存在 Memtest86+ 运行中显示错误。
最可能的解释是计算是否成功取决于正在使用 RAM 的哪一部分。而 Argon2——现在是密钥派生的默认值——在计算过程中使用了大量内存。
但这不是 cryptsetup 的错。现在,我再次测试了一个内存块,该内存块至少通过了一次 Memtest86+ 运行。它不再是可复制的。两个版本 (
< pw
和cat pw |
) 现在总是通过。更新:我通过移除 RAM 插槽做了更多测试。有趣的是,它适用于单个插槽,但组合起来就变得不可靠了。机器本身是新的,但我看到启用了XMP(Extreme Memory Profile) 。根据我的阅读,这是新硬件上合理的安全默认设置,但在我的机器上它似乎会导致问题。禁用它后,它现在可以工作了。
也许他们应该在 memtest86+ 中包含 Argon2。在我的系统上,检测内存问题非常有用。