我的USB闪存盘带有隐藏加密保险库

Hacker News Top 产品

摘要

一个名为Phantomdrive的开源硬件项目创建了一种USB闪存盘,它显示为一个小磁盘,同时隐藏了一个AES-256加密分区,以保护数据免受胁迫。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/21 18:39

# 我在构建一款能自行隐藏的安全USB驱动器 来源:https://rootkitlabs.com/2026/06/22/I'm-Building-a-Secure-USB-Drive/ *本文由人类撰写,面向人类。* --- 许多地方不尊重隐私法律,在某些情况下,你可能被迫解密存储介质,更糟糕的是,甚至会被假定有罪。VeraCrypt 隐藏卷在前一种情况下有用,但在后一种情况下却无能为力。 这就是我创建 Phantomdrive 的原因。 Phantomdrive 是一款完全开源的 USB 驱动器(https://github.com/o7-machinehum/phantomdrive),首次插入时显示为 8 GB 的驱动器。操作系统无法检测到磁盘的剩余部分。如果用户在磁盘上编辑一个包含内容 `password:PUTYOURPASSWORDHERE` 的纯文本文件,它会自行卸载并重新挂载第二个隐藏分区,并就地执行 AES-256 加密/解密。 有了 Phantomdrive,希望你能避开威权政府代表、腐败警察以及其他不尊重基本加密权利的人。 ## 设计 一切完全开源:固件、硬件和机械工程。我用于设计该设备的工具也是开源的。让我们深入了解设计! 在这个项目中,我使用了一个有趣的小芯片,叫做 **CH569**。它来自生产 USB 转串口芯片 **CH340**(几乎每款仿冒 Arduino 上都有的芯片)的同一家公司。 对于这个项目,我利用了 USB3、SD/eMMC 和 AES 模块。你在上面看到的 SM4 加密模块,据维基百科称,是*中国商用密码标准化*的一部分。 由于 AI 需求,eMMC 存储器的价格异常高昂,所以我选择使用 SD 卡作为存储器。如果拆开设备,有人会找到你的 SD 卡,但当然所有内容都是加密的。我用环氧树脂将外壳粘合在一起,这意味着攻击者若想进入内部,必须破坏设备。如果这不满足你的需求,我建议你另寻他法 😊 一旦 eMMC 价格下降,将会有使用它的版本。 该设备很简单,只包含 CH569、USB 端口、两个降压电源、一个用于固件更新的按钮、SD 卡和一些支持元件。还有 UART 测试点,有助于固件开发。 ## 密码学 当“人们”在我的仓库上打开几个 AI 生成的 GitHub 问题时,我没有收到通知。它们概述了一系列问题:已经修复的问题、AI 幻觉、以及被夸大其词的小问题。Reddit 迅速跟风,而我当时正在睡觉。 这是我的一大失误,我至少应该注意到有人打开了问题。其中大部分不是真正的问题,除了 AES-XTS,我将在下面讨论。 至于设备的安全性,我已经通过功能测试(如这个:https://github.com/o7-machinehum/phantomdrive/blob/master/test/kdf.c)进行了验证,你可以在此确认加密是否正常工作,并与 OpenSSL 的 AES 实现进行了对照验证。 ## 密钥派生函数(KDF) KDF,即密钥派生函数,是一种用于生成加密密钥的函数。我们先从最差劲的 AES 密钥派生方式开始。 $$ K = Pw \|\| 0x000 $$ 我们取密码,用零填充直到 32 字节(用于 AES-256),这就是我们的密钥。如果使用糟糕的密码,比如“password1234”,我们可以在几分钟内暴力破解。使用好密码则变为几个小时,而使用非常好的密码可能需要几年甚至几十年。 但如果攻击者使用预计算的密钥表怎么办?这意味着他们甚至不需要计算任何东西。为了解决这个问题,我们添加了一个盐值。 $$ K = Pw \|\| salt \|\| 0x000 $$ 如果每个设备都有唯一的盐值,攻击者需要针对每个设备计算密钥,那么查找表问题就消失了。由于盐值不同,你不能将 SD 卡从一个设备取出并放入另一个设备。以下是获取盐值的方法…… `` udevadm info --query=property --name=/dev/sdc | grep ID_SERIAL_SHORT ID_SERIAL_SHORT=Phantomdrive:34FC1FA7145467F7 `` 所以 34FC1FA7145467F7 是该设备的盐值,如果你的设备损坏,数据恢复时需要用到它。顺便提一下:你可以通过更改固件将“Phantomdrive”和 USB PID/VID 改为任何你想要的,以增加隐蔽性。 现在假设我们的攻击者有一台非常强大的机器,拿到了你的盐值,然后开始计算他们自己的“表”。为了让这变得更难一些,我们在 KDF 中增加了 100,000 轮 SHA-256。 $$ K = sha256(sha256(sha256(Pw \|\| salt \|\| 0x000))) ... 100k $$ 我选择 100,000 轮,因为设备解锁大约需要 3 秒,再增加轮数会更慢。我无法使用 Argon2 等算法,因为它们需要大量内存。如果你有更好的方法,且不使解锁过程超过 5 秒,我很乐意听取建议,但目前我们已经达到了该设备的计算极限。 如果你需要更高的安全性,可以增加 KDF SHA256 轮数、寻找其他设备,或者使用软件解决方案对该设备进行双重加密。也可以直接关闭加密,仅使用基于软件的加密。 ## AES 模式 AES 是一种分组密码,意味着它可以加密和解密固定大小(16 字节)的数据。有多种不同的 AES 模式可将其转换为流密码。 ### AES-ECB AES-ECB(电子密码本)是一种朴素的流密码实现方式。你只需将流中的每个 16 字节明文块分别加密。瞧!我们刚做了一个流密码。但这并不安全,原因如下: 1. 相同的明文块会产生相同的密文块,导致扩散性不足。 2. 攻击者可以移除密文中的部分数据,解密后明文会以可预测的方式被修改。 所以这不是一个好方法。 ### AES-CTR AES-CTR(计数器)是一种解决上述问题的方法。它的工作方式很简单:对计数器进行 AES 加密,然后将输出与明文进行异或。 `` uint64_t i = 0; while(i < len(ciphertext)) { ctr = aes_encrypt(i); ciphertext[i] = plaintext[i] ^ ctr i++; } `` 这是伪代码,但你应该明白了。 使用此模式时需要注意一个安全风险:“计数器重用”。 1. 攻击者获取了你的密文,将设备放回原处。 2. 你写入大量新数据。 3. 攻击者再次获取你的密文。 4. 如果攻击者能猜出其中一个密文,就能恢复另一个密文。 在这款设备上,使用 AES-CTR 时写入速度约为 9MB/s,读取速度约为 20MB/s;使用 AES-XTS 时写入速度约为 6MB/s,读取速度约为 10MB/s。对我来说,在速度上牺牲这么多换来的安全性提升并不值得转向 AES-XTS,但你的情况可能完全不同。 ### AES-XTS AES-XTS(带调整的密码本模式)是磁盘加密的标准。它使用两个密钥:\\(K_1\\) 是数据密钥,\\(K_2\\) 用于生成调整密钥。 对于每个磁盘扇区,需要根据扇区编号 \\(S\\) 计算调整密钥。 $$ T_n = AES(K_2,S) $$ 每个 16 字节块都有自己的调整值,因此你会得到 \\(T_0\\)、\\(T_1\\)、\\(T_2\\) ... \\(T_n\\)。然后逐块加密明文 \\(P\\),得到最终的密文 \\(C\\)。 $$ C_n = AES(K_1, (P_n \oplus T_n)) \oplus T_n $$ 这解决了上述计数器重用的问题,但速度稍慢。 ## 固件 我使用了两个项目,感谢它们的维护者。 - 芯片的库(BSP):https://github.com/hydrausb3/wch-ch56x-lib - ISP 编程库:https://github.com/hydrausb3/wch-ch56x-isp 固件中有几个部分你可能感兴趣…… ## 密码嗅探 该设备实际上并不了解文件系统,它只是将 USB WRITE10/READ10 命令转换为 SD 卡的 CMDx 命令。因此,为了实现解锁的魔法,我们只需查看原始数据。在锁定状态下,它看起来像这样。 `` void phantomdrive_snoop_write(uint8_t *buf, uint32_t len) { const char *prefix = "password:"; const size_t prefix_len = 9; uint32_t i; for (i = 0; i + prefix_len <= len; i++) { if (buf[i] != 'p') continue; if (memcmp(buf + i, prefix, prefix_len) != 0) continue; size_t pw_start = i + prefix_len; size_t pw_end = pw_start; while (pw_end < len && (pw_end - pw_start) < sizeof(pending_pw) && buf[pw_end] != '\n' && buf[pw_end] != '\r' && buf[pw_end] != '\0') pw_end++; size_t pw_len = pw_end - pw_start; // 将密码复制到 RAM 中 memcpy(pending_pw, buf + pw_start, pw_len); pending_pw_len = pw_len; // 然后我们将此缓冲区清零,以便 // 密码永远不会写入磁盘 memset(buf + i, 0, pw_end - i); return; } } `` 该设备不了解文件系统,因此在锁定状态下,它会在每次写入前调用此函数。它监视所有写入,并匹配 `password:`。这意味着如果你在磁盘的不安全部分使用大量数据,且数据中包含字符串 `password:`,则可能意外触发匹配。同样,如果这不满足你的需求,你可以更改它或寻找其他设备。 ## 结尾 感谢阅读和支持这个项目。开发过程很有趣,并在社区中引起了广泛兴趣。这种互动正是激励我继续从事这类工作的动力。 如果你对支持这个项目感兴趣,我们现在已上线预购页面!(https://rootkitlabs.com/phantomdrive) --- Ryan Walker #### Ryan Walker 用开源工具构建开源项目。

相似文章

使用 Passkey 解锁加密的 ZFS 卷

Lobsters Hottest

本文介绍了 Revaulter v2,这是一个允许在启动时使用 Passkey(WebAuthn)解锁加密 ZFS 卷的工具。它支持通过移动端 Web 界面进行远程审批,且无需以明文形式存储密钥。

veracrypt/VeraCrypt

GitHub Trending (daily)

VeraCrypt 是一款基于 TrueCrypt 7.1a 并进行了安全增强的免费磁盘加密软件。该存档包含其源代码以及适用于 Windows、Linux、macOS 和 BSD 的构建说明。