Yubikey 安全密钥折腾记(2):使用入门
自从上次使用 Cloudflare Zero 的优惠买下两个 YubiKey 之后,这俩玩意被我搁置了一个学期。原因之一是学习成本不低,关于它们的文档、教程都充斥着不少不太了解的名词、概念,令人望而却步。于是经过查阅各种资料,在这篇博客中我将(用白话文)介绍我从零开始的 YubiKey 入门之旅。
Yubico 与 YubiKey
Yubico 是一家美国的公司,是 YubiKey 的制造商。(这家公司似乎对东亚某国有一定政治倾向。这一点我不了解也不评论。)
YubiKey 是这家公司生产的硬件安全密钥。这个东西有点像以前很多银行要用的「U 盾」,是硬件层面保障安全性的一个东西。
我购买的是 YubiKey 5 系列,包含一个 YubiKey 5 NFC 和一个 Yubikey 5C NFC(Type-C 接口)。本文只介绍这两个设备支持的功能。这个设备上有一个可以触摸的按钮和指示灯。
软件安装
官方有三个软件:
YubiKey Manager:简单易用的跨平台 GUI 的 YubiKey 管理器。相比于命令行,这个软件对于新手来说友好很多。本文我主要使用这个软件来管理 YubiKey。非常推荐安装。YubiKey Personalization Tool:更加专业的管理工具,有 GUI 和 CLI 两个版本。自由度更高。似乎已经停止更新。这个软件在我的 macOS 上文字显示特别模糊,不知道是为啥。Yubico Authenticator:一个 App,用于生成二次验证的密码(生成时需要 YubiKey 验证),类似于 Google Authenticator。不同之处在于真正秘密的信息都存储在 YubiKey 硬件上,通过很强的加密机制保障安全性。手机上可以通过 NFC 和 YubiKey 交互。安装 YubiKey Manager 后,插入 YubiKey 它就可以识别到。可以看到支持的三个主要应用:OTP、FIDO2 和 PIV,这是三个相互独立的功能。在 Interfaces 里则可以控制各种功能的开关。
设置前准备……
理论上,为了保证较高的安全性,接下来的操作都应该在一台全新安装的、断开网络连接的 USB 镜像(比如 Ubuntu Live)或者虚拟机中进行;所有生成的临时文件都应该放在重启后就消失的 tmpfs 里。如果确实有特殊的需求,可以配置这样的环境,不过对于个人而言应该没什么必要。
OTP
OTP 的全称是 One-Time Password,即一次性密码。这个功能是将 YubiKey 作为一个模拟键盘,在短按或长按硬件按钮后,可以在电脑上输入密码(并回车)。
刚拿到 YubiKey 还没有配置的情况下,插入电脑,触摸按键,会发现输入了一段长长的乱码。这就是默认配置的 Yubico OTP。(在 macOS Ventua 中,建议不要在中文输入法开启时按下……否则会卡死。)
短按和长按两个 slot 可以分别配置。每个 slot 有四种选项:
Yubico OTP:Yubico 自己的一种协议,需要客户端支持。基于时间生成一串的密码。出厂时是和 YubiCloud 绑定的,如果删除了可能需要重新和 YubiCloud 绑定。一般用不到。(短按的 slot 默认是这个设置)Challenge-response:「质询 - 响应」模式,也需要第三方软件的配合。一般用不到。Static password:顾名思义是可以设置一个静态的文本,作为常用的密码,每次触摸就可以自动输入密码。这个比较有用。(毕竟,在键盘上输入密码时,手指传递给键盘的温度、敲击键盘发出的声音,都可能导致侧信道攻击(笑))OATH-HOTP:Open Authentication HMAC-based One-Time Password,其中 HMAC 指的是 Hash-based Message Authentication Code。这是一种开放的 OTP 协议,目前不知道有什么用。以上个人目前感觉最有用的就是 Static password,将它设置成自己常用的密码就可以免输入了。
个人认为安全领域的 challenge 这个词应该翻译成「质询」更加贴切,而不是「挑战」。
Slot
上面提到了 slot(插槽)的概念,OTP 这个功能中有两个 slot,下面的 PIV 则有 25 个 slot。可以将 slot 理解为存储单元,每个 slot 有一个地址,如这个文档中列出了 PIV 的 25 个 slot 以及各自的地址。
FIDO
FIDO 的全称是 Fast IDentity Online。Yubico 是标准化机构 FIDO Alliance 的一员,遵循后者制定的 FIDO 标准。
YubiKey 支持两种 FIDO 标准:FIDO U2F(Universal Second Factor)和 FIDO2。前者可以理解为第一代协议,后者是第二代。
设置 PIN
所谓 PIN 指的是 Personal Identification Number,这个概念在各种地方都有,比如 Windows 可能会让你设置登录 PIN(这样登录系统时无需输入密码,只需输入 PIN。许多人分不清这两个概念),早期本地化不好的 Android 手机里的锁屏密码也叫做 PIN。它和「password」这个概念的区别在于:一般 PIN 只包含四位或六位数字,更加简单,适用于需要更频繁输入的情况。
在使用 FIDO 之前,要先设置 FIDO PIN,默认是没有的。这个 PIN 需要至少四个字符。
WebAuthn(2FA)
FIDO 最常用的应用就是 WebAuthn。这个协议允许我们在浏览器中将硬件密钥作为 2FA 的手段。
所谓的 2FA 指的是 Two-Factor Authentication,即两步验证(双因素验证),也叫做 MFA(Multi-Factor Authentication)。因为纯粹「用户名 + 密码」的登录组合安全性太低,密码泄漏将等同于账号失窃。所以许多网络服务登录时在密码之外增加了一个验证因素,故名曰「双因素」。比如 QQ 的「设备锁」,在陌生设备上登录时,除了要求密码正确,还要输入收到的手机短信验证码,这就是一种 2FA。
一般来说,2FA 有这几种比较常用的形式:
短信、电话、邮箱验证。这种国内的应用比较常见。TOTP(Time-based One Time Password),一般需要用户安装 Google Authenticator 之类的手机 App,经过扫码配置等之后,里面会显示一个每 30 秒刷新一次的 6 位动态密码,需要输入这个动态密码。(早期「QQ 安全中心」里的「动态令牌」就是这个东西,只是它协议不开放)WebAuthn,使用兼容 FIDO2 协议的硬件来认证,比如 YubiKey。最近比较流行的 Passkey(通行密钥)也属于此。其他冷门的协议,比如下图 VaultWarden 支持的「YubiKey OTP 安全钥匙」,就是前文所述 OTP 功能里的 Yubico OTP 的协议。上面提到的 WebAuthn 就是 FIDO 的一项功能。国外如 Google、Microsoft、Apple 等的应用基本都支持这个协议,可能由于 FIDO Alliance 在国内影响力有限,国内应用很少支持。可以在 https://webauthn.me 测试 WebAuthn 功能。
由于我使用的 BitWarden 本身支持设置 TOTP 作为各种 2FA 并且非常方便,我只有在自己 VaultWarden 实例的登录上使用了 YubiKey 作为 2FA。
SSH via FIDO
OpenSSH 从 8.2 版本开始,登录时也支持 FIDO 标准的 2FA。可以参阅:通过 FIDO2 加固 SSH。简单来说,只要:
ssh-keygen -t ed25519-sk
使用这样生成的密钥,在登录时会需要 YubiKey 二次验证。所以即使攻击者拿到了密钥,也无法登录。
但是相比之下,我更希望「不需要存储密钥」,通过 YubiKey 直接登录(也就是将密钥存储在 YubiKey 里)。这可以通过下面的 PIV 实现。
PIV
PIV 的全称是 Personal Identity Verification。这个功能允许我们在 YubiKey 里保存 GPG 密钥等。存储在其中的密钥文件不可导出,可以保障安全性。
YubiKey Manager 软件只支持管理四个 slot 里存放的证书。更多的功能可以使用命令行工具 yubico-piv-tool
。
PIN、PUK 与 Management Key
PIV 的 PIN 默认是 123456
。PIN 要求 6~8 个字符,每个字符可以是任意 ASCII 字符。PIV PIN 只有三次尝试机会,如果三次都错误,PIN 将会被 block,这时候不能再输入。(注意,PIV PIN 和 FIDO PIN 无关)
PUK 即 PIN Unlock Key,用于在 PIN 锁定时解锁设备。默认是 12345678
。PUK 实际上是一个 8 Byte 值,每个 Byte 允许 0x00
到 0xFF
,所以不仅允许 ASCII 字符,也允许不可见字符。PUK 也只有三次尝试机会,如果三次都错误,PUK 也将被 block。此时 PIV 会彻底被锁定,只能重置 PIV 功能——也意味着其中的所有密钥永远消失。
Management Key 是一串长长的字符串,默认是 0x010203...
,设置时可以生成一个新的值。在执行一些重要操作时需要输入。它没有尝试次数限制,不会被 block。
PIN、PUK 的尝试次数限制默认为 3,可以用高级工具配置这个值。如果 PIV 被锁定,对其他应用(OTP、FIDO2)没有影响。
这篇文档介绍了 PIN、PUK 与 Management Key。
PIN-only 模式
由于 Management Key 太长,PIV 提供 PIN-only 模式,即在所有操作中只需要 PIN 不需要 Management Key。具体来说,有两种模式:
PIN-protected:将 Management Key 存储,用 PIN 保护。PIN-derived:根据 PIN 生成 Management Key。PIN-derived 模式下,由于 Management Key 不会被 block,攻击者可以通过枚举 PIN 暴力破解,所以不建议使用此模式。
YubiKey Manager 软件中,在设置 Management Key 的时候,默认可以设置 PIN-protected 模式。
Certificates
进入 PIV 中 Certificates 的设置,可以看到可以存放四种证书:
Authentication(slot9A
):用于用户认证的证书,一般用于系统登录。Digital Signature(slot 9C
):用于数字签名的证书。Key Management(slot 9D
):用于 confidentiality 加密的证书。Card Authentication(slot 9E
):用于智能卡的证书,通常用于获取访问权限。每个 slot 都可以生成、导入、导出证书等。
对于 YubiKey 生成的证书,我们只能导出证书本身,至于对应的私钥文件是不能导出的。这确保了安全性。
SSH via PIV
理论上来说,将 SSH 的密钥存储在 YubiKey 里(是无法取出的),使用 ssh-agent
可以通过其连接 SSH。但是官方的教程非常陈旧,网上找的各种教程也都不适用于我的 M1 MacBook macOS。所以这项还在研究中,估计等这个系列的下一篇可以写。
参考
Setup - Yubico - 写在包装纸背面的 Getting Start 网址。.NET YubiKey SDK: User's Manual - 虽然是面向开发人员的 SDK 手册,但是其中对于功能的介绍比较详细,适合想要搞清楚「这是什么东西」的普通用户。Securing SSH with the YubiKey - 官方的文档,提供了各种用 YubiKey 加固 SSH 的方式。drduh/YubiKey-Guide: Guide to using YubiKey for GPG and SSH - 一份完备的 GPG 和 SSH 配置教程。比较硬核。文章来源:
Author:SkyWT
link:https://blog.skywt.cn/posts/yubikey-intro