做了一个用于登录 SSH 的 USB Key,成本低至 9.9 元

2022-01-26 22:47:01 +08:00
 44670
由于直接用密码不方便并且不安全,相信很多人都会配置使用公私钥来登录 SSH 主机。
然而,直接在电脑里存储私钥文件实际上是非常不安全的:电脑上任何一个能读取用户目录的软件都有可能偷走私钥然后做坏事。
比较可信赖的方式是做一个专门的 USB Key 设备,实现 SSH 登录时用到的公私钥认证算法,这样一来电脑上就不会存储私钥了。
YubiKey 支持 SSH 登录,但是除了价格问题以外,另一个问题是 YubiKey 对 SSH 登录的支持不是原生的,在 Windows 下需要依赖 Windows Crypto API/SmartCard API 这些黑箱,其它平台上也需要 OpenPGP 这样的软件套一至多层实现,配置起来可能会很复杂并且总觉得不够可靠。

所以我觉得有必要自己做一个专门用于登录 SSH 的 USB Key ,并且尽量简化功能和降低成本。

基于以下几点原因,最后选择了 ESP32/ESP32-C3 芯片:
1. ESP32 系列自带安全启动、存储加密功能,一定程度上可以防止硬件上的秘密被物理读取。
2. 价格非常便宜,目前淘宝上卖得最多的一家 ESP32-C3 开发板只需 9.9 元(限购 10 件)。
3. 有 WiFi/BLE 功能,未来或许可以做成无线的。

已经在 ESP32 开发板上测试通过,几乎所有的 ESP32/ESP32-C3 开发板都可以直接使用。

也在计划做自己的硬件,打算提供一个带灯的按钮,用户按下物理按钮可以确认登录操作。

PC 端用 Go 实现了一个 ssh-agent ,可以转发 SSH 身份认证请求到设备端、由设备端完成签名操作。

特点:
1. 设备端只专注 ed25519 签名一件事情,代码<1K LOC (不含第三方库),容易审计。
2. 私钥完全在设备端产生,不会传递到外部,不依赖 Windows Crypto API/SmartCard API 之类的黑箱。
3. 私钥通过 SHA256 算法,结合设备端存储的随机种子+用户密码产生。设备本身不存储 /验证某个特定的用户密码,用户每次输入不同的密码即可以直接使用不同的 ed25519 公私钥对。
4. 使用外部的独立 USB 转串口芯片,避免软件 USB 协议栈的潜在漏洞影响设备的安全性。
5. 可以通过单一的 Go 写的工具,实现设备的初始化、ssh-agent 等全部功能,不需要安装额外的软件。

使用方法:
1. 安装 ESP-IDF 环境、构建 44Key 项目后刷入任意一个 ESP32/ESP32-C3 开发板里。
2. 运行 44KeyTool -port COMx -format ,初始化设备。需要在键盘上随便输入些字符,用于给设备端生成随机种子提供一部分熵。(在设备管理器里确认具体的串口号,替换 COMx )
3. 运行 44KeyTool -port COMx ,输入自己的密码后,即可开启 ssh-agent ,此时终端会显示输出公钥。
4. 把公钥添加到目标服务器的~/.ssh/authorized_keys ,下次就可以直接用 USB Key 登录啦。

项目地址:
硬件(准备中): https://oshwhub.com/44670/miniusbkey
固件: https://github.com/44670/44Key
PC 端软件: https://github.com/44670/44KeyTool

目前是一个可以在 Windows 上工作的原型,实现了 SSH 认证所需的全部功能,不过安全启动和存储加密还没默认启用。

欢迎提供各种想法!
10606 次点击
所在节点    分享创造
103 条回复
ysc3839
2022-01-27 09:05:03 +08:00
@adoal 个人在用 HT42B534 的 USB 串口,这个是直接用 USB CDC 协议的。不选 CH340 是因为以前用的是 PL2303 的,然后厂家在新驱动里去掉了旧芯片的支持,用旧驱动时不时会蓝屏,最终只能直通进 Linux 虚拟机里用,超麻烦。
loading
2022-01-27 09:17:50 +08:00
前段时间做了个 canokey ,还没正式用,焊接难度爆表( t12 小 k 头)
https://github.com/canokeys/canokey-hardware
knightdf
2022-01-27 09:34:16 +08:00
@lucifer9 自己电脑从来不加,麻烦自己
lucifer9
2022-01-27 09:43:49 +08:00
@knightdf 麻烦在哪里呢,不管是 ssh-agent 还是 gpg-agent 不都挺方便的么,当然要是经常重启自己机器那当我没说
BQsummer
2022-01-27 10:27:02 +08:00
@shunia 我妈问我整天画蚯蚓干啥
cnkuner
2022-01-27 10:31:06 +08:00
问一下,硬件出问题了怎么办,比如产品的 USB 挂了。
Dreax
2022-01-27 10:33:43 +08:00
@44670 https://github.com/cnlohr/espusb 有人做了纯软件 USB 不知道怎么样
t123yh
2022-01-27 10:41:09 +08:00
@44670 esp32s2 支持 USB
cccer
2022-01-27 10:42:14 +08:00
@cnkuner 硬件 KEY 一般都是设置 2-3 个,主 KEY 坏了可以先用备用的登录。
ihipop
2022-01-27 10:53:32 +08:00
要是坏了,和所有机器失联。。
什么⊙∀⊙?备份一个秘钥在机器上?那有什么意义?
CallMeReznov
2022-01-27 10:57:41 +08:00
CH340 在 centos 的驱动甚至需要自己重新编译替换,否则工作上不是太顺利
具体可以看这个
https://github.com/juliagoda/CH341SER
jiezhi
2022-01-27 11:17:56 +08:00
不懂硬件,能不能用个虚拟磁盘(可加密)模拟这个 USB ?用的时候挂载,不用的时候卸载。
adoal
2022-01-27 11:25:55 +08:00
@jiezhi USB key 和 U 盘的区别。前者是个计算设备,私钥不出 key ,电脑上获取不到私钥内容,后者哪怕盘是加密的但文件总要被原样读入到电脑一次。
jiezhi
2022-01-27 11:28:15 +08:00
@adoal #33 明白了
yolee599
2022-01-27 11:28:56 +08:00
使用串口还要安装驱动,USB CDC 的话也要驱动,而且换一个 USB 接口串口号就变了。最好用 USB HID ,免驱,通过 VID/PID 识别设备,不用关心串口号的问题
EPr2hh6LADQWqRVH
2022-01-27 11:33:02 +08:00
像这种设备能够很好抵御灰尘水淹撞击强磁静电吗。。

我的 AMD 显卡现在猫从旁边过就能挂逼,已经 PTSD
adoal
2022-01-27 11:38:38 +08:00
@yolee599 串口号变的原因是握手时返回的设备 ID 里没有序列号字段,这个不难解决。至于驱动,Windows 10 已经带公版 sys 和 inf 了,7 和 8 里其实有 sys ,只是缺一个不挑 VID/PID 的 inf 而已,这个倒也也不难解决。
44670
2022-01-27 11:56:39 +08:00
@lucifer9 那个如果密码简单的话是容易被暴力破解的,设置复杂的密码又会容易觉得麻烦。
44670
2022-01-27 11:58:07 +08:00
@t123yh 软件的 USB 协议栈容易出现安全问题,iPhone 和 Switch 的 bootrom 都有翻车的历史。
44670
2022-01-27 12:01:28 +08:00
@cnkuner 我的理解是 SSH Key 一般是即抛型的,如果丢失了就应该在服务器上重新设置别的公钥。

如果加密货币硬件钱包的话,会在生成密钥的同时输出一套助记词,可以把它写在纸上用于找回私钥。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/830808

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX