使用 Waveshare RP2350-One 制作一个开源版 YubiKey
前言
第一次听说 YubiKey 大约是在十多年前,当时觉得一个硬件的安全密钥“很酷”,但是搜了一下淘宝的售价直接给我劝退了。现在 YubiKey 在淘宝的售价虽然有所降低,但是依然需要 300 多块,不过我们已经有了低成本的开源替代选择:Pico FIDO2。
硬件选择
Pico FIDO2 支持多种硬件,我选择的是微雪(Waveshare)推出的 RP2350-One,这也是网上教程主流的选择,价格约在 30 人民币上下,包邮,非常便宜。
固件与刷机流程
Pico FIDO2 的固件可以到仓库的 Release 上找到,对于本文使用的 Waveshare RP2350-One,我们需要 pico_fido2_waveshare_rp2350_one-x.x.uf2
Waveshare RP2350-One 的刷机流程也非常简单,只需要按住 Boot 键插入电脑,他就会被识别为一个 U 盘,直接把需要刷入的 uf2 固件拖入其中即可完成固件刷写与重启,非常方便,不过为了让 Pico FIDO2 的固件正确刷入(可以使用 Yubico Authenticator 等软件),我们还是需要遵循一定的流程,以下流程参考此文并结合个人实践得出:
- 按住
Boot,插入电脑 - 把
pico_fido2_waveshare_rp2350_one-x.x.uf2拖入 RP2350 中,等待一会 - 拔出 RP2350
- 插入 RP2350(这次不要按任何按键)
- 在 Pico Commissioner 调试,选项如下,其中 Product Name 为
Yubico YubiKey:
调整完选项后,点击 Commission via WebUSB 选择红框的设置直接照搬我的选项即可,这里着重解释一下绿框的两个选项。
对于物理密钥来说,面对物理接触攻击时的安全性很重要。开启 Secure Boot 和 Secure Lock 可以防止未授权的固件运行或访问芯片内的密钥,从而保护设备免受篡改和数据泄露。
但代价是该开发板日后只能运行 Pico Keys 的官方固件,该选择不可逆。
如果你是打算进行二次开发、DIY因此需要自签,那么就不要开启绿框的两个选项。但如果你打算将其作为日常使用的物理密钥,那我强烈建议你打开这两个选项。Pico Key并连接,然后点击Commission via WebAuthn,并选择写入物理密钥,根据操作系统引导进行配置。 - 拔出,插入,打开 Yubico Authenticator 或 YubiKey Manager,可正常显示。
此处的重点就在于刷写完固件后拔插一次 RP2350,如果不这么干的话虽然固件明面上正常可用,但 Yubico Authenticator 和 YubiKey Manager 无法正常识别 RP2350 为 YubiKey。
如果遇到问题,可以使用 Pico Nuke 清空所有数据再次刷写,具体的操作是在上面的 1 和 2 之间加入一条:
- 把
pico_nuke_waveshare_rp2350_one-1.4.uf2拖入 RP2350 中,等待其再次作为 U 盘出现。
使用与管理
普通的 YubiKey 所支持的功能,基本上 Pico Key 都支持,但是要注意部分功能(PIV 与 OpenGPG)被作者拆分成了多个部分,不过 Pico FIDO2 固件本身支持 FIDO2 和 OATH,对于大多数人来讲够用了。
对于正确刷写了固件的 Pico Key,你可以直接通过 Yubico Authenticator 进行使用与管理,或者通过命令行工具 ykman 进行使用与管理。有关 ykman 的部分可以直接参考这篇文章,本文选择更加方便的 Yubico Authenticator。
在使用密钥的过程中,经常能看到的一句提示是“触摸密钥”,对于 Pico Key,这里指的是按下 Boot 按键。
OATH
在 Yubico Authenticator 左栏选择“账户”,点击右边的“添加账户”即可添加 TOTP 或 HOTP 的 OATH 到账户中。
不过我大多数使用 OATH 的场景都不太适合用一个物理密钥,个人认为 OATH 的部分使用自建的 Bitwarden 更加可靠和实用。当然,决定选用那种 OATH 方式是根据个人需求决定的,Pico Key 与 Bitwarden 各有各的优劣。
FIDO2
这才是我对物理密钥需求更大的部分。
WebAuth
FIDO2 可以通过 WebAuth 作为无密码登录的 Passkey 或 2FA 的 Second factor。比如对于 Google 账户来说,在 账户设置 - 安全性 - 通行密钥和安全密钥 部分就可以添加各种类型的通行密钥:
此处选择“换部设备”(默认是添加到 Windows Hello)即可将通行密钥添加到 Pico Key 当中:
其他服务商同理,只要提供了 WebAuth 支持的服务商均可使用这种办法将密钥添加到 Pico Key 当中。
SSH
FIDO2 也可以用于 SSH 私钥,只需要生成带硬件校验的密钥对即可:
1 | ssh-keygen -t ed25519-sk -C "[email protected]" |
这种方法需要硬件和私钥同时存在才能使用,从安全性角度来讲这么做是正确的,但是从使用角度来讲我还是更希望物理密钥本身可以单独使用,或者能够存储私钥。于是我们可以考虑添加 resident 选项:
1 | ssh-keygen -t ed25519-sk -O resident -O verify-required -C "[email protected]" |
顺便可以加上
-O verify-required,要求每次使用时均需输入PIN码并进行物理触摸操作(OpenSSH 8.3及以上版本)。
这样生成的密钥可以在任一台电脑上通过命令 ssh-keygen -K 取回密钥对(Windows 上需要管理员权限,否则报错),之后可以正常进行密钥校验。此处同上,只有硬件和私钥同时存在才能使用,因此导出的私钥并不能在缺少硬件的情况下单独使用,安全性也有所保障。
话虽如此,实际使用效果不佳,详见后文:个人遇到的已知问题
当然,支持硬件的 SSH 认证并不只有这一种,比如 Securing SSH with OpenPGP or PIV,不过我本人对此需求并不多(因为我不会在一台陌生的设备上操纵登陆 SSH,我的 SSH 也无法在不通过加密隧道的情况下连接)此处不多赘述。
外壳
外壳部分我使用的是 pat.vdleer 的模型,感谢他的作品,不过顶盖部分可能会在安装时直接卡住按钮,所以我提交了一个裁切版的顶盖模型打印配置可供选择。
个人目前遇到的已知问题
- Pico Key 理论上是支持 PAM 的,但是我在 Linux 下设置成功后,一插拔 Pico Key 似乎密钥会变动(?),最终导致 PAM 认证失败。
- 在 Windows 端的 Yubico Authenticator 可以看到添加的通行密钥,但是在 Android 端看不到,不过通行密钥本身存在并可以进行 Passkey/2FA。TOTP正常显示。
基于 FIDO2 的 SSH 密钥存在一定的问题,似乎和 OpenSSH 版本与平台有关。我在 Windows 上的 OpenSSH for Windows 9.5 生成的密钥在Linux上提取后无法使用,而 Arch 上的 OpenSSH 10.2p1 生成的密钥直接无法在 Windows 下提取,我尝试升级 OpenSSH for Windows 9.8p2 也无济于事。
最后我尝试直接将 Arch 上生成的密钥拷贝到 Windows 下,发现居然可以直接使用,但Android端的 Termius 又无法直接导入这个密钥。顺便一提我服务端是运行在 Ubuntu Server 上的 OpenSSH 9.6p1,理论上版本不应该成为问题。
问题似乎是因为我使用 Bitwarden 导致的,因为 Bitwarden 在 Windows 下接管 SSH 代理的前提是禁用 OpenSSH Authentication Agent 服务。虽然报错不是同一个,但可以肯定的是影响与干扰的确存在。
总结
总体而言实际上体验一般,当然大多数问题并非是 Pico Key 项目的问题,而是标准在不同平台、版本下支持不佳的问题,很多问题我想即便是换到真正的 YubiKey 体验未必一定很好。
我最失望的是当年觉得 Yubikey “很酷”的一个原因在于我以为他可以像一把赛博钥匙一样,插到电脑上,解锁系统。但对于 Windows 来说,Smart Card 是为企业管理提供服务,没办法在个人操作系统上作为类似 Windows Hello 的方式登陆系统(查询资料时似乎看到有人通过 Bug 实现了,但是这违背了安全的本质)。而 Linux 平台虽然理论上可以通过 PAM 实现,但正如前文所述的问题,我并没能成功实现。
目前全平台使用无障碍无门槛的就只有 OATH 和 WebAuth,前者不需要额外配置,后者基于浏览器统一标准实现,因此在不同平台不同环境下都有着良好的使用体验。对于我个人来说,我更倾向于将 OATH 存放在 Bitwarden 中,原因在于使用上的便利。
而绝大多数可以设置通行密钥的网站,我都将 Pico Key 添加其中,因为这些网站确实会有在陌生设备/新设备登陆的需求,而在每台设备、每个浏览器上都安装 Bitwarden 并合理设置,这显然是不可能也不安全的,此时实体密钥在保证安全下的便捷性就体现出来了。
尤其是我有很多服务本身没提供公网安全性,但我有需要将其暴露在公网使用,甚至在完全陌生的设备上使用。以前通过 Basic Auth 做防护,安全性本身不高不说,还巨麻烦。有了 Pico Key 之后,通过 Authelia 与 Authentik 即可为相关公网服务提供 TOTP 与 Passkey 支持,既安全又便捷。
参考
- RP2350刷Pico Fido教程_YubiKey(FIDO2安全密钥,助你远离网络钓鱼) 新的优化
- 30 元低成本自制开源版 Yubikey (支持 FIDO2 的硬件安全密钥)
- Securing SSH Authentication with FIDO2 Security Keys