我正在调试 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 相同的行为。
答案1
@frostschutz 是正确的。事实证明,我机器上的内存在 Memtest86+ 运行中显示错误。
最可能的解释是计算成功或失败取决于正在使用 RAM 的哪一部分。 Argon2(现在是密钥派生的默认值)在计算过程中使用大量内存。
但这不是 cryptsetup 的错。现在,我再次测试了仅一个内存块,该内存块至少通过了一次 Memtest86+ 运行。它不再可重现。两个版本(< pw
和cat pw |
)现在总是通过。
更新:我通过移除 RAM 插槽进行了更多测试。有趣的是,它适用于单独的插槽,但组合起来就变得不可靠。机器本身是新的,但我看到了XMP(极限内存配置文件)已启用。据我了解,这在新硬件上是合理的安全默认设置,但在我的机器上它似乎导致了问题。禁用后,现在可以使用了。
也许他们应该在 memtest86+ 中包含 Argon2。在我的系统上,检测内存问题非常有用。