基于Teensy 4.1的硬件密码保险箱DIY:从加密原理到工程实践
1. 项目概述:为什么我们需要一个硬件密码保险箱?
在数字生活里,密码管理器已经成了必需品。从浏览器插件到独立的桌面应用,它们确实方便,把我们从记忆几十个复杂密码的苦海中解救出来。但不知道你有没有想过一个问题:这些软件,终究是运行在你的电脑或手机操作系统上的。你的操作系统里,除了密码管理器,还跑着成千上万个其他进程——浏览器、邮件客户端、后台更新服务,甚至是你无意中下载的某个小工具。任何一个进程如果被恶意软件劫持或本身就是恶意的,理论上都有可能窥探到密码管理器内存中的数据,或者通过键盘记录、屏幕截图等方式窃取你的主密码。软件层面的安全,就像把宝藏锁在一个有很多扇门和窗户的房间里,你永远无法确定是否有一扇窗忘了关。
这就是硬件隔离(Hardware Isolation)理念的价值所在。把最敏感的操作——加密、解密、密钥存储——放到一个独立的、功能单一的硬件设备里去完成。这个设备只干这一件事,没有复杂的操作系统,没有网络栈,更没有其他乱七八糟的进程。它就像一个物理的“保险箱”,你的秘密只在里面被处理,与外部那个充满潜在威胁的计算环境完全隔离开。我这次折腾的 Midbar (Teensy 4.1) V3.0 项目,就是基于这个思路的一次实践。它本质上是一个基于 Teensy 4.1 高性能微控制器的独立硬件密码保险箱。
这个DIY项目能做什么?很简单,也很核心:安全地存储你的登录凭证(用户名、密码、网站)和信用卡信息。你可以通过USB键盘来操作它,所有数据在存入设备时,会经过一个我称之为“丧心病狂”的加密链(3DES + AES + Blowfish + Serpent,工作在CBC模式)进行加密,并用HMAC-SHA256来保证数据完整性。加密后的数据可以选择存储在芯片内部的EEPROM(断电不丢失的存储器,空间有限但速度快),或者外接的Micro SD卡上(空间近乎无限)。当你需要用时,解锁设备,它可以把密码“敲”进你的电脑——对,它自己可以模拟成一个USB键盘,自动输入,你连看都不用看,避免了被肩窥或截屏的风险。
适合谁来玩这个项目?如果你是对嵌入式开发、硬件安全有兴趣的开发者、极客,或者单纯是对现有软件密码管理器心存疑虑,想拥有一个完全由自己掌控的“物理密码本”的安全爱好者,那么这个项目会是一个绝佳的起点。它不只是一个焊接和刷固件的体力活,更涉及加密算法应用、存储管理、人机交互设计等一系列有趣的问题。接下来,我会带你从设计思路到每个焊点,从加密原理到避坑指南,完整地复现这个硬件数据保险库。
2. 核心设计思路与安全架构解析
2.1 硬件选型:为什么是Teensy 4.1?
市面上微控制器那么多,从Arduino Uno到ESP32,为什么这个项目选择了Teensy 4.1?这背后是性能、接口和生态的综合考量。
首先,加密是计算密集型任务。我们采用的加密链(后面会细说)涉及多次块加密操作,对处理器的算力有一定要求。Teensy 4.1搭载了NXP的i.MX RT1062跨界MCU,这是一颗主频高达600 MHz的Cortex-M7内核。对比常见的AVR(16 MHz)或ESP8266(80-160 MHz),它的计算能力有数量级的提升。这意味着加密解密操作几乎是瞬间完成,用户不会有明显的等待感,体验流畅。我曾尝试在性能较弱的板子上跑同样的算法,输入一个长密码后要等上好几秒,体验非常糟糕。
其次,丰富的内置存储和接口。Teensy 4.1自带8MB的Flash(用于存储程序)和1MB的RAM,这为相对复杂的菜单系统和数据缓冲区提供了充足空间。更重要的是,它板载了一个Micro SD卡槽。对于密码管理器这类应用,存储扩展能力至关重要。内部EEPROM(通过模拟实现,约1KB)容量有限,只能存少量核心凭证(如最常用的16组登录信息)。而SD卡可以让你存储成百上千条记录,包括那些不常用但必须记住的各类账户信息。此外,它原生支持USB Host功能,这意味着我们可以直接连接USB键盘作为输入设备,无需额外的USB Host Shield模块,简化了硬件设计。
最后,强大的社区与库支持。PJRC为Teensy提供了极其优秀的Arduino核心兼容库和Teensyduino插件,使得在Arduino IDE下开发变得非常方便。像我们需要的TFT显示屏驱动(Adafruit_ST7735)、加密算法库(虽然部分需要自己实现或整合)等,都有成熟的生态支持。这大大降低了开发门槛,让我们能把精力集中在应用逻辑和安全设计上,而不是底层驱动调试。
注意:Teensy 4.1的IO引脚是3.3V电平,且不兼容5V。在连接外部器件(如显示屏)时,务必确认其工作电压。错误接入5V信号可能会永久损坏芯片。
2.2 安全架构核心:加密链与完整性验证
软件密码管理器的核心是加密算法。Midbar V3.0的安全模型建立在两个支柱上:一个强大的加密链,和一个可靠的完整性验证机制。
1. 加密链:3DES + AES + Blowfish + Serpent (CBC Mode)
看到这一串名字,你的第一反应可能是“过度设计”或“套娃”。确实,在密码学中,通常认为一个经过充分验证的强算法(如AES-256)就足够了。我设计这个加密链的初衷,更多是出于一种“深度防御”的思维实验,并解决早期版本中的一个设计缺陷。
- 什么是超级加密(Superencryption)? 正如NIST所定义的,它指的是对已经加密过的密文再次进行加密的操作。我们这个加密链就是依次执行:明文 -> 3DES加密 -> AES加密 -> Blowfish加密 -> Serpent加密 -> 最终密文。理论上,这样一个串联的强度至少不低于其中最强的那个算法,并且由于组合了不同的算法和更长的总体密钥长度,可能会对某些针对特定算法的未知攻击增加额外的抵抗力,同时也会输出熵值更高的密文。
- 为什么是CBC模式? 这是我从V2.0版本升级到V2.5版本时一个关键的修正。早期版本使用了一种类似ECB的怪异模式。在ECB模式下,相同的明文块会产生相同的密文块。攻击者虽然不能通过交换密文块来构造合法密文(因为每个块都单独用HMAC保护了),但他可以将密文A的第n块,替换为密文B的第n块。解密后,对应的明文块就会被替换,可能导致信息泄露或篡改。切换到CBC(密码块链接)模式后,每个明文块在加密前,都会先与前一个密文块进行异或操作。这样,如果攻击者替换了中间任何一个密文块,不仅会导致该块解密出的明文乱码,还会级联影响到下一个块的解密,因为下一个块的解密依赖于被篡改的密文块。这使得对密文的任何局部篡改都会产生全局性的、明显的错误,更容易被完整性检查发现。
- 密钥派生与主密码:所有加密算法的密钥,都部分派生自用户设置的主密码。这意味着,即使有人物理上拿到了你的Teensy设备和解密固件,没有你的主密码,他也无法推导出正确的加密密钥来解密数据。这是密码管理器的安全基石。主密码本身并不直接存储,而是通过一个密钥派生函数(在代码中实现)来生成加密所需的各个密钥分量。
2. 完整性验证:HMAC-SHA256
加密保证了机密性,但无法防止密文被篡改。攻击者可能通过物理方式(如对EEPROM/SD卡进行位翻转攻击)或软件漏洞来修改存储的密文。为了检测这种篡改,Midbar使用了基于HMAC-SHA256的消息认证码。
- 工作原理:当用户保存一条记录(例如一组账号密码)时,Midbar会先将所有字段(用户名、密码、网站)拼接成一个完整的字符串,然后使用一个独立的认证密钥(同样由主密码派生)计算这个字符串的HMAC-SHA256值,得到一个“标签”(Tag)。这个标签随后被加密,并与加密后的数据一起存储。
- 验证过程:当用户读取记录时,设备先解密数据,再解密之前存储的标签。然后,它对刚解密出来的明文数据重新计算一次HMAC-SHA256标签。最后,比较新计算的标签和解密出来的旧标签是否一致。
- 结果:如果两者匹配,说明数据自存储以来未被篡改。如果不匹配,Midbar会明确提示“完整性验证失败”,警告用户数据可能已损坏或被恶意修改。这就像在保险箱上贴了一张特殊的封条,一旦被打开或调包,封条就会断裂。
实操心得:关于“位翻转攻击” 原文提到这种攻击“kinda works”。在嵌入式环境中,由于宇宙射线、电源波动等原因,存储单元(如EEPROM)确实可能发生位翻转(0变1或1变0)。HMAC-SHA256对此非常敏感,哪怕只改变一个比特,计算出的标签也会截然不同,从而被检测到。所以,虽然攻击在物理上可能发生,但几乎不可能“悄无声息”地通过完整性验证。这反而体现了HMAC在这种场景下的价值。
2.3 存储策略:EEPROM与SD卡的分工
Midbar采用了分层存储策略,兼顾了速度、安全性和容量。
-
EEPROM(内部存储):
- 特点:速度快,访问延迟极低,与MCU内核紧密耦合。但容量非常小(Teensy 4.1通过Flash模拟的EEPROM约1KB)。
- 用途:用于存储最核心、最常用的少量记录(设计容量为16组登录信息+12组信用卡信息)。因为空间宝贵,这里做了一些优化:所有记录共享一个初始化向量(IV),并且对整个EEPROM数据区进行一次性的完整性校验,而不是为每条记录单独存储HMAC标签。这样可以节省大量空间。
- 优点:访问迅速,适合存放需要快速调用的核心密码(如电脑登录密码、邮箱主密码)。
- 缺点:容量硬伤,无法扩展。
-
Micro SD卡(外部存储):
- 特点:容量巨大(以GB计),可以存储海量记录。但访问速度相对较慢,且是物理上可移除的介质。
- 用途:存储大量的、不常使用的记录。每条记录都拥有自己独立的IV和HMAC-SHA256标签,安全性更高。理论上,只要卡空间足够,你可以存储成千上万条记录。
- 优点:容量无限,便于备份(可以直接复制卡上的加密文件到电脑)。
- 缺点:SD卡有寿命限制(读写次数),且物理上可能丢失或损坏。因此,定期备份SD卡数据是必要的。
这种设计非常实用:把高频、核心的数据放在快速的“内存保险箱”(EEPROM),把低频、归档的数据放在大容量的“仓库保险箱”(SD卡)。你需要权衡的是,哪些密码值得占用宝贵的EEPROM空间。
3. 硬件组装与核心电路详解
3.1 物料清单与采购建议
要复现这个项目,你需要准备以下核心部件。我在这里列出了一些选购时的注意事项,能帮你避开不少坑。
| 部件 | 数量 | 说明与选购建议 |
|---|---|---|
| Teensy 4.1 开发板 | 1 | 项目的核心。务必确认是4.1版本,它带有SD卡槽。4.0版本没有,需要额外接模块。 |
| 1.77英寸 TFT LCD 显示屏 | 1 | 驱动芯片需为 ST7735。这是最常见的一种,价格便宜,库支持完善。注意分辨率为128x160。 |
| USB-A 母座 | 1 | 用于连接USB键盘。可以从旧的电脑机箱前面板扩展挡板上拆,或者单独购买。 |
| USB键盘 | 1 | 任何标准USB全尺寸或迷你键盘均可。用于输入主密码和操作菜单。 |
| Micro SD 卡 | 1 | 可选,但强烈推荐。用于扩展存储。容量无需太大,1GB或2GB足够,但必须格式化为 FAT32 文件系统。 |
| 杜邦线(公对公、公对母) | 若干 | 用于连接各部件。建议多备一些不同长度的。 |
| 面包板或PCB | 1 | 用于固定和连接电路。初期验证用面包板,想做成品可以考虑设计或购买一个简单的PCB。 |
| 5V / 3.3V 电源 | 1 | Teensy 4.1可通过USB口供电,非常方便。 |
关于显示屏的特别提醒:市面上ST7735驱动的1.77寸屏有很多变种,它们的引脚顺序、背光控制方式可能不同。最常见的是带CS, RST, DC, MOSI, SCK, VCC, GND, BL 这8个引脚的模块。其中 BL(背光) 引脚的处理方式五花八门:有的要求接3.3V常亮,有的要求接GND常亮,有的可以通过PWM调光,还有的可以不接。在连接前,最好找到你这款屏的数据手册或卖家提供的说明。一个安全的做法是:先不接BL,如果上电后屏幕不亮,再尝试接3.3V或GND。
3.2 电路连接图与接线表
硬件连接非常简单,本质上就是把屏幕和USB口接到Teensy 4.1对应的引脚上。下图是核心的连接示意图,你可以根据这个在面包板上搭建。
(此处为文字描述连接图,实际项目中可配图) 想象一下,Teensy 4.1开发板水平放置。我们将屏幕和USB口连接到其右侧的引脚排针上。
| Teensy 4.1 引脚 | 连接至 | 功能说明 |
|---|---|---|
| 3.3V | 显示屏 VCC | 为屏幕提供3.3V电源。绝对不要接错到5V! |
| GND | 显示屏 GND, USB口 GND | 共地。 |
| PIN 7 | 显示屏 CS (Chip Select) | 片选信号,低电平有效。 |
| PIN 8 | 显示屏 RST (Reset) | 复位信号,低电平复位。 |
| PIN 20 | 显示屏 DC (Data/Command) | 数据/命令选择线。 |
| PIN 21 | 显示屏 MOSI (Master Out Slave In) | SPI数据线,主设备输出。 |
| PIN 14 | 显示屏 SCK (Serial Clock) | SPI时钟线。 |
| BL引脚 | 根据屏幕型号接 3.3V 或 GND | 背光控制。先悬空测试,不亮再试接3.3V或GND。 |
| 5V | 仅连接 USB口的 VCC (红) | 重要:只给USB口供电!Teensy引脚不兼容5V! |
| GND | USB口的 GND (黑) | 共地。 |
| D+ (Pin 24) | USB口的 D+ (绿) | USB数据线+。 |
| D- (Pin 25) | USB口的 D- (白) | USB数据线-。 |
接线核心要点:
- 电源隔离:确保屏幕的VCC只接Teensy的3.3V。USB口的5V红线只接Teensy的5V引脚,千万不要把USB口的5V误接到屏幕或Teensy的任何数据引脚上,那会烧毁芯片。
- SPI引脚:Teensy 4.1有多个SPI接口,我们使用的是默认的SPI(MOSI=21, SCK=14)。代码中也是这么定义的,不要接错到其他SPI引脚(如11,13)。
- USB Host:Teensy 4.1的USB Host功能是通过特定的D+和D-引脚(24和25)实现的,必须接对。
3.3 焊接与组装注意事项
如果你打算做一个永久性的设备,而不是在面包板上测试,那么焊接是必要的步骤。
- 焊接顺序:建议先焊接USB母座和屏幕的排针到一块洞洞板或定制PCB上,然后再用杜邦线或导线连接到Teensy的排母上。Teensy本身可以先不焊死,插在排母里,方便后续调试和更新固件。
- 防短路检查:焊接完成后,务必用万用表的蜂鸣档仔细检查相邻引脚、电源与地之间是否有短路。这是避免上电“放烟花”的最关键一步。
- 机械固定:考虑为屏幕和Teensy设计或3D打印一个外壳。这不仅美观,更能保护电路,防止引脚意外短路。一个带按钮的开关键也是个不错的附加功能。
- 上电前最后确认:对照接线表,再肉眼检查三遍。特别是5V线是否只接到了USB口,以及屏幕VCC是否接的是3.3V。
4. 软件环境搭建与固件烧录
4.1 安装Arduino IDE与Teensyduino插件
Midbar的固件是基于Arduino框架编写的,所以我们需要Arduino IDE作为开发环境,并为其添加Teensy 4.1的支持。
- 下载Arduino IDE:前往Arduino官网下载最新稳定版的IDE。安装过程很简单,一路下一步即可。
- 下载并安装Teensyduino:这是PJRC官方提供的插件,包含了Teensy系列板子的核心库、编译器链和烧录工具。
- 访问PJRC的下载页面:
https://www.pjrc.com/teensy/td_download.html - 运行下载好的Teensyduino安装程序。它会自动检测你电脑上已安装的Arduino IDE路径。
- 在组件选择页面,务必勾选“Teensy 4.1”。下方的库可以全选安装,或者至少确保安装了“USBHost_t36”(用于USB键盘支持)和“SD”(用于SD卡读写)。
- 完成安装。
- 访问PJRC的下载页面:
安装完成后,打开Arduino IDE,在“工具” -> “开发板”菜单中,你应该能看到“Teensy 4.1”的选项了。
4.2 获取与准备Midbar固件
Midbar的源代码是开源的,你可以从两个地方获取:
- SourceForge(推荐):
https://sourceforge.net/projects/midbar/这里提供的是精简版,只包含Teensy 4.1 V3.0的固件和密钥生成工具,下载速度快(约3.4 MB)。 - GitHub:
https://github.com/Northstrix/Midbar这里是完整的仓库,包含所有历史版本、额外代码、图片和图表,但体积巨大(约323 MB)。除非你想研究其他版本,否则下载SourceForge的包就够了。
下载并解压后,你会看到类似Teensy 4.1 Version/V3.0/这样的目录结构。里面有几个关键文件夹:
Clear_EEPROM/:用于清空EEPROM的固件。Firmware/:主固件源代码。Untested RNG/:一个未经验证真随机性的密钥生成工具(gen.exe,仅Windows)。
4.3 安装必要的第三方库
Midbar的显示部分依赖Adafruit的图形库。你需要手动安装它们。有两种方法:
方法一(推荐,管理方便):
- 打开Arduino IDE。
- 点击“项目” -> “加载库” -> “管理库...”。
- 在库管理器中搜索“Adafruit GFX”,找到并安装“Adafruit GFX Library”。
- 同样地,搜索并安装“Adafruit ST7735”和“Adafruit BusIO”。 IDE会自动处理依赖关系。
方法二(手动安装):
- 从GitHub下载库的ZIP包:
- Adafruit-GFX-Library:
https://github.com/adafruit/Adafruit-GFX-Library - Adafruit-ST7735-Library:
https://github.com/adafruit/Adafruit-ST7735-Library - Adafruit_BusIO:
https://github.com/adafruit/Adafruit_BusIO
- Adafruit-GFX-Library:
- 在Arduino IDE中,点击“项目” -> “加载库” -> “添加.ZIP库...”,然后分别选择你下载的三个ZIP文件。
安装完成后,重启Arduino IDE以确保库被正确加载。
5. 固件配置、密钥生成与首次启动
5.1 清空EEPROM
在第一次使用Midbar之前,必须清空Teensy的EEPROM。因为固件会读取EEPROM中的特定区域来判断是否已初始化。如果里面残留着旧数据,可能导致程序行为异常或无法启动。
- 在Arduino IDE中,打开
Clear_EEPROM文件夹下的.ino文件。 - 在“工具”菜单中,确保“开发板”选为“Teensy 4.1”,“USB类型”暂时保持默认即可。
- 点击上传按钮(向右的箭头)。程序编译完成后,Teensy Loader会自动弹出。
- 按下Teensy 4.1板上的白色小按钮(Program按钮),等待程序烧录完成。
- 烧录完成后,程序会自动运行一次,完成EEPROM的清零。你可以通过串口监视器(波特率9600)看到“EEPROM Cleared”的提示。
5.2 生成并替换加密密钥
这是整个项目安全性的最关键一步! Midbar固件中预置的密钥只是示例。如果你不替换成自己生成的密钥,那么任何拥有相同固件的人都能解密你的数据。密钥生成必须使用可靠的随机源。
警告:项目提供的gen.exe工具作者明确声明未经过严格的随机性测试,无法保证其生成的密钥是密码学安全的。仅建议用于测试和学习目的。对于真实用途,你应该使用经过验证的随机数生成方法。
推荐的安全密钥生成方法:
- 在Linux/macOS上:使用
/dev/urandom。打开终端,输入:这会生成一个128个十六进制字符(64字节)的随机字符串。你可以多生成几次,拼接成所需长度。BASHhead -c 64 /dev/urandom | xxd -p -c 64 - 使用密码学库:如果你会编程,用Python的
os.urandom()或secrets模块、OpenSSL命令行工具等生成随机字节,再转为十六进制。 - 专用硬件:使用真正的硬件随机数生成器(HRNG)。
假设你决定使用项目提供的gen.exe工具(理解其风险):
- 运行
Untested RNG文件夹下的gen.exe。 - 点击“Gen. keys for Midbar (Teensy 4.1) V3.0”按钮。界面背景变灰表示正在生成。
- 生成的密钥会显示在下方的大文本框中。请立即将这些密钥完整地复制并保存到一个安全的、离线的地方(例如用加密笔记软件记录,或打印出来物理保存)。一旦丢失,你将永远无法解密设备中的数据。
接下来,替换固件中的密钥:
- 用Arduino IDE打开
Firmware文件夹下的Firmware.ino文件。 - 在代码开头部分,你会看到一系列
byte数组的定义,例如byte first_key[32] = { ... };。这些就是预置的密钥。 - 仔细地用你刚刚生成并保存的密钥十六进制字符串,替换掉这些数组中的所有内容。确保格式正确,每个十六进制数前都有
0x,并用逗号分隔。 例如:将0x00, 0x01, ...替换为你的0xAB, 0xCD, ... - 务必检查:替换后,数组的长度必须和原来完全一致。一个字符的错误都会导致加解密失败。
5.3 自定义其他参数(可选)
在替换密钥的附近,你还可以调整一些参数来个性化你的Midbar:
你可以根据自己的喜好调整字段长度分配(但总和不能变)和界面主题色。颜色是16位的RGB565格式。
5.4 编译与上传主固件
- 在Arduino IDE的“工具” -> “USB类型”菜单中,必须选择“Serial + Keyboard + Mouse + Joystick”。这是为了让Teensy能够同时作为串口设备(用于调试)和USB键盘(用于自动输入密码)工作。
- 点击上传按钮。
- 在编译完成后,Teensy Loader再次弹出时,按下Teensy板上的Program按钮。
- 等待上传完成。现在,你的硬件密码保险箱已经就绪。
6. 系统操作指南与核心功能详解
将组装好的设备通过USB线连接到电脑(仅供电),连接好USB键盘,插入格式化为FAT32的Micro SD卡(如果需要使用扩展存储)。设备上电后,屏幕会显示“Midbar Teensy 4.1”和“Press Any Key”的锁屏界面。
6.1 初始化:设置主密码
按下键盘任意键后,系统会提示你设置一个主密码。这是整个设备的“总钥匙”。
- 重要性:主密码用于派生加密和完整性验证的密钥。它不会被存储在任何地方。忘记主密码,意味着设备内的所有数据将永久无法解密。同时,没有正确的主密码,设备甚至无法解锁进入主菜单。
- 设置建议:使用高强度、易记忆但他人难以猜测的密码或口令。避免使用生日、常见单词等。
- 操作:用键盘输入你的主密码,然后按
Enter或Esc键确认。输入时屏幕可能显示*号或直接隐藏,这是正常的安全措施。
6.2 主菜单导航与基本操作
成功解锁后,你会进入主菜单。操作逻辑非常直观:
↓(下箭头):向下移动光标。↑(上箭头):向上移动光标。Enter(回车):进入选中的菜单或确认操作。Esc或Backspace(退格):返回上一级菜单或取消当前操作。
主菜单通常包含:“Logins In EEPROM”(EEPROM中的登录信息)、“Logins On SD Card”(SD卡中的登录信息)、“Credit Cards”(信用卡信息,同样分EEPROM和SD卡)、“Encryption Algorithms”(加密算法工具)、“Other Options”(其他选项,如备份恢复)等。
6.3 EEPROM与SD卡记录管理实操
我们以“登录信息”为例,详解其完整的增、删、改、查流程。信用卡信息的操作逻辑完全相同。
1. 添加记录到EEPROM:
- 路径:主菜单 ->
Logins In EEPROM->Add-> 选择空槽位 ->USB Keyboard。 - 随后依次输入:
Username(用户名) ->Password(密码) ->Website(网站)。 - 注意:EEPROM只有16个槽位,每个字段的长度受前面
#define定义的限制。输入时会实时显示剩余字符数。
2. 从EEPROM查看记录:
- 路径:
Logins In EEPROM->View-> 选择槽位。 - 屏幕会分页显示用户名、密码和网站。密码默认是隐藏的(显示为)*,这是一个基本的安全特性。
3. 使用“Type”功能自动输入: 这是Midbar最实用的功能之一。当你在电脑上需要登录某个网站时:
- 在Midbar上导航到对应记录:
Logins In EEPROM->Type-> 选择槽位。 - 此时,Midbar会模拟成一个USB键盘。将电脑的输入焦点放到浏览器密码框。
- 在Midbar上按
↑键,它会依次自动输入“网站URL”、“用户名”、“密码”,并自动在输入用户名后加入Tab键切换,在输入密码后加入Enter键提交(具体行为取决于固件实现)。 - 优势:全程密码不显示在电脑屏幕上,避免了被截屏或远程桌面偷窥的风险。也无需手动敲打复杂密码。
4. 删除EEPROM记录:
- 路径:
Logins In EEPROM->Delete-> 选择槽位 -> 确认。
SD卡的操作与上述流程几乎一致,区别在于:
- 容量无限:在
Add时,你可以选择任意一个“虚拟”槽位(如001, 002...),系统会在SD卡上创建对应的加密文件。 - 独立完整性校验:每条记录都有自己的HMAC标签,安全性更高。
- 编辑功能:SD卡记录支持
Edit,可以修改特定字段(如只改密码)。EEPROM记录不支持编辑,只能删除后重新添加。 - 打印到串口:在
ViewSD卡记录时,多了一个选项可以将解密后的明文(谨慎使用!)输出到串口监视器,方便在无屏幕的极端情况下调试或查看。
6.4 加密算法工具箱的使用
主菜单中的“Encryption Algorithms”是一个独立的工具集,允许你直接使用Midbar内置的7种加密算法(包括那个四重加密链)对任意字符串进行加密和解密。这对于验证加密功能、或者临时加密一段文本非常有用。
加密字符串:
- 打开Arduino IDE的串口监视器(波特率通常为9600)。
- 路径:
Encryption Algorithms-> 选择算法(如3DES+AES+Blowfish+Serpent(CBC)) ->Encrypt String-> 选择输入源(USB键盘或串口)。 - 输入你想加密的明文。加密后的密文(十六进制格式)会输出到串口监视器。请及时保存,因为它不会显示在屏幕上。
解密字符串:
- 确保串口监视器已打开。
- 路径:
Encryption Algorithms-> 选择之前加密时用的算法 ->Decrypt String-> 选择输出位置(屏幕或串口)。 - 根据提示,将之前保存的密文(十六进制字符串)粘贴到串口监视器的输入框,然后点击“发送”。
- 解密后的明文会显示在你选择的位置。
实操心得:串口通信的坑 在使用串口监视器粘贴密文时,确保没有多余的空格或换行符。有些串口工具会自动在末尾加换行,这会被当作输入的一部分,导致解密失败。最好在代码中或操作时,明确要求以特定字符(如
#)作为结束符,或者使用“Raw Input”模式。
6.5 数据备份与恢复
这是一个非常重要的维护功能。
- 备份EEPROM到SD卡:路径:
Other Options->Back Up Data From EEPROM->SD Card。这会将EEPROM中所有加密数据打包成一个名为Midback的文件保存到SD卡根目录。定期执行此操作,可以防止因EEPROM物理损坏或固件错误导致的核心数据丢失。 - 从SD卡恢复EEPROM:路径:
Other Options->Restore Data To EEPROM->SD Card。这会读取SD卡上的Midback文件,并将其内容覆盖到EEPROM。注意:恢复操作会覆盖当前EEPROM中的所有数据! - 工厂重置:在
Other Options菜单中可能还有“Factory Reset”选项。这会清空EEPROM和SD卡上Midbar创建的所有数据,包括备份文件,并将主密码重置。这是一个不可逆的核弹级操作,使用时务必三思。
7. 常见问题排查与深度优化建议
即使按照教程一步步来,你也可能会遇到一些问题。这里我总结了一些常见的坑和解决办法。
7.1 硬件连接与电源问题
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 屏幕上电无任何显示 | 1. 电源未接通或接错。 2. 背光(BL)引脚未正确连接。 3. 屏幕损坏。 |
1. 用万用表检查Teensy的USB口是否有5V输入,3.3V引脚是否有输出。 2. 尝试将屏幕BL引脚接3.3V或GND。 3. 检查SPI引脚(CS, RST, DC, MOSI, SCK)是否连接牢固。 4. 尝试另一个已知好的屏幕。 |
| 屏幕显示乱码或花屏 | 1. SPI通信速率不匹配或干扰。 2. 电源噪声大。 3. 屏幕初始化代码有误。 |
1. 检查杜邦线是否过长(>20cm),尽量缩短。 2. 在VCC和GND之间靠近屏幕处并联一个10uF和0.1uF的电容滤波。 3. 确认代码中 Adafruit_ST7735的构造函数引脚顺序与你的接线一致。 |
| USB键盘无反应 | 1. USB口接线错误(D+, D-接反)。 2. USB口供电不足。 3. 固件中USB类型未设置正确。 |
1. 确认USB口的D+(绿)、D-(白)线是否分别接Teensy的24和25脚。 2. 尝试使用带外部供电的USB Hub连接键盘,或换一个功耗更小的键盘。 3. 务必确认Arduino IDE中“USB类型”设置为“Serial + Keyboard + Mouse + Joystick”。 |
| Teensy无法被电脑识别或无法烧录 | 1. USB线问题(只能充电,无数据线)。 2. Teensy的Bootloader损坏。 |
1. 换一根确认可以传输数据的USB线。 2. 尝试短接Teensy背面的“Program”引脚(或通过按钮)强制进入Bootloader模式,再用Teensy Loader工具手动烧录。 |
7.2 软件与功能异常
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 编译错误,提示库找不到 | 库未正确安装或路径错误。 | 1. 在Arduino IDE的“文件”->“首选项”中查看“项目文件夹位置”。确保库安装在正确的libraries子目录下。2. 尝试通过库管理器重新安装Adafruit相关库。 |
| 程序上传后,设备反复重启或卡住 | 1. EEPROM未清空或内容混乱。 2. 密钥替换错误。 3. 堆栈溢出或内存不足。 |
1. 首先执行“清空EEPROM”步骤。 2. 仔细核对替换的密钥数组,长度和格式必须完全匹配。一个字节错误就会导致解密失败,进而可能引发程序逻辑错误。 3. 尝试在代码中减少一些缓冲区大小或简化菜单,但V3.0版本通常内存充足。 |
| SD卡无法识别或读写失败 | 1. SD卡未格式化为FAT32。 2. SD卡接触不良。 3. 文件系统损坏。 |
1. 使用电脑将SD卡格式化为FAT32(注意:大于32GB的卡Windows可能不提供FAT32选项,需用第三方工具)。 2. 重新插拔SD卡,确保完全插入Teensy卡槽。 3. 在电脑上使用 chkdsk或磁盘工具修复SD卡。 |
| “Type”功能输入错乱 | 键盘布局或输入速度问题。 | 1. 确保电脑的键盘布局(如美式、英式)与Midbar模拟输入时预期的布局一致。代码中可能默认是美式布局。 2. 在固件中,可以尝试在 Keyboard.print()语句之间增加短暂的delay(),给电脑系统足够的时间处理按键事件。 |
| 完整性验证失败 | 1. 数据被篡改(极罕见)。 2. 存储介质(EEPROM/SD卡)出现位错误。 3. 加密/解密密钥不一致。 |
1. 如果发生在SD卡上,尝试将卡内文件备份后,重新格式化SD卡再恢复数据。 2. 如果发生在EEPROM上,尝试从备份恢复。如果没有备份,数据可能已损坏。 3. 最可能的原因:你修改了主密码,或者固件中的密钥被更改,但试图解密用旧密钥加密的数据。密钥必须始终保持一致。 |
7.3 安全强化与进阶优化建议
如果你不满足于基础功能,这里有一些可以深入探索的方向:
-
引入真正的硬件随机数生成器(HRNG):Teensy 4.1没有内置HRNG。你可以外接一个如
ATECC608A的加密芯片,它不仅能提供高质量随机数,还能安全地存储密钥,实现真正的“密钥不出芯片”,安全性再上一个台阶。 -
增加物理防拆机制:在外壳内部增加一个轻触开关或簧片开关,当外壳被打开时,开关断开,触发程序立即擦除EEPROM中的敏感数据或使主密码失效。
-
实现双因子认证(2FA):可以结合一个外接的矩阵键盘或指纹模块,实现“密码+物理令牌”或“密码+指纹”的双重认证,才能解锁设备。
-
优化用户界面:目前的导航完全依赖键盘方向键。可以考虑增加一个旋转编码器或几个独立按键,让操作更符合直觉。也可以优化屏幕显示,比如使用更小的字体显示更多信息,或增加电池电量显示(如果改用电池供电)。
-
开发桌面端管理工具:通过串口通信,编写一个电脑端的图形化程序,用于批量导入/导出密码(当然是加密后的)、管理记录、更改设置等,提升易用性。
-
审计与简化加密链:从密码学工程角度,四重加密链增加了复杂性,但未必按比例增加安全性。你可以研究并测试,是否可以将加密链简化为AES-256-GCM(同时提供加密和完整性验证),在保证安全的同时提升性能和代码可维护性。
这个基于Teensy 4.1的硬件密码保险箱项目,从一个有趣的想法出发,融合了嵌入式硬件、密码学应用和实用主义的安全设计。它最大的魅力不在于使用了多么高深的技术,而在于提供了一种看得见、摸得着、完全受控的数据安全方案。从焊接第一根线,到生成自己的密钥,再到成功存储并自动输入第一个密码,整个过程充满了动手的乐趣和对安全原理的深入理解。希望这份详细的指南,能帮助你成功构建属于自己的那个数字秘密堡垒。