做了一个用于登录 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 认证所需的全部功能,不过安全启动和存储加密还没默认启用。

欢迎提供各种想法!
11372 次点击
所在节点    分享创造
103 条回复
adoal
2022-01-26 22:48:38 +08:00
好新潮,居然用 RISC-V
44670
2022-01-26 22:50:00 +08:00
@adoal RISC-V 很便宜!
thedrwu
2022-01-26 22:54:42 +08:00
yubikey 嫌太贵,之前有人用这个搞过 1$的 openpgp key 。看了一眼过程,没 3d 打印机打印壳。放弃
44670
2022-01-26 22:58:07 +08:00
@thedrwu M5Stack 做了好多款带外壳的开发板,不过价格稍微贵了点。
adoal
2022-01-26 23:00:21 +08:00
不是很建议用 CH340 ,一来这玩意需要装厂家的私有协议驱动,二来它不加外部闪存的话 USB 没有序列号字段(它的阉割版 CH341 甚至连加闪存放序列号的可能性都没有),换换槽插可能 COM 端口号就变掉了。最好是选一个用 CDC/ACM 协议的,并带序列号字段的。MCU 的 USB 协议栈一般都有 CDC/ACM 的 sample ,不过你担心协议栈实现不靠谱的话那不太好找,容易买到的大概只有 Holtek 的。
44670
2022-01-26 23:01:48 +08:00
@adoal 在考虑外挂一个便宜的 USB MCU ,bl702 那种似乎还不错。
44670
2022-01-26 23:02:56 +08:00
@adoal 有一个新出的 CH343P ,内置 EEPROM 可以配置 VID/PID ,淘宝上 9.9 ESP32C3 开发板用的正好就是那个。
mineralsalt
2022-01-26 23:12:25 +08:00
没这个必要吧, 如果个人电脑数据都沦陷了, 那那那, 不用活了
adoal
2022-01-26 23:20:19 +08:00
@44670 查了一下居然是 CDC/ACM 和私有双协议的……
44670
2022-01-26 23:23:22 +08:00
@adoal M1 Mac 也能支持了
rockyzhang
2022-01-26 23:28:23 +08:00
EdDSA 默认用了 SHA-512 吧,用不着再弄一个 SHA-256 的库了,好像 MCU 也带 SHA 硬件加速器和 TRNG
https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
44670
2022-01-26 23:38:55 +08:00
@rockyzhang 感谢提醒!

确实可以把 ed25519-donna 的 sha2 实现替换掉(之前以为 ed25519 用的是 sha3 )。

ESP32 自带了 SHA 加速器,不过应该不打算去用那个。

硬件 TRNG 利用了 RF 电路的无线噪声,似乎得初始化整个 WiFi 才可用。

目前用的是 esp32 bootloader 使用的 RNG ,熵源是内部的 ADC 电路。ESP-IDF 文档推荐在不用 WiFi 的情况下可以用这个。
shunia
2022-01-27 00:31:31 +08:00
每次看你们这些搞硬件的聊天,都有一种我妈看我写代码的既视感
november
2022-01-27 00:43:24 +08:00
ssh -i /u 盘 /.ssh/key user@domain
cweijan
2022-01-27 01:07:56 +08:00
666, 很酷的想法
zagfai
2022-01-27 02:29:22 +08:00
@november 根本不是一回事。。。。
lucifer9
2022-01-27 07:26:43 +08:00
不是,你们生成 ssh key 都不用 passphrase 的?
Chad0000
2022-01-27 07:59:14 +08:00
@shunia #13 对于软件开发人员来说,就像产品经理看代码。稍稍好那么一丢丢。
zliea
2022-01-27 08:49:53 +08:00
我觉得还是做一个手机蓝牙的 ssh key 吧。
讲道理有硬件一是不方便,二是绝大部分人都是把 Key 插在电脑上不动了,其实和扔计算机上没毛线区别。
如果担心 ssh key 被读取,ssh key 有加密。
zliea
2022-01-27 08:52:45 +08:00
@lucifer9 一般自己电脑上不加,只有远程的机器上加一个。

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

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

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

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

© 2021 V2EX