我的USB闪存盘带有隐藏加密保险库
摘要
一个名为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 卷
本文介绍了 Revaulter v2,这是一个允许在启动时使用 Passkey(WebAuthn)解锁加密 ZFS 卷的工具。它支持通过移动端 Web 界面进行远程审批,且无需以明文形式存储密钥。
这款美得奇妙的项链,竟然是个USB驱动器
Noware的Puff项链是一款可穿戴科技配件,兼具USB驱动器功能,配备可定制LED屏幕,兼顾美观与实用,预计十月发货。
为巴士底日发布的 Trusty Boot Key(Ventoy 替代品)
一款名为 Trusty Boot Key 的新型开源工具提供了 Ventoy 的替代方案,用于创建可启动 USB 驱动器,于巴士底日发布。
使用AES-256-GCM和USB密钥加载的文件夹加密C++ CLI
一个用C++编写的Linux CLI工具,使用AES-256-GCM加密文件夹,通过加密映射隐藏文件和文件夹名称,并支持基于USB的密钥加载。
veracrypt/VeraCrypt
VeraCrypt 是一款基于 TrueCrypt 7.1a 并进行了安全增强的免费磁盘加密软件。该存档包含其源代码以及适用于 Windows、Linux、macOS 和 BSD 的构建说明。