注意:此文主要针对 Yubikey 4。但 Yubikey 5 与 4 差别不大,大部分操作是通用的。

最近入手了一个 Yubikey,正好花点时间配置一下。

缘起

话说从去年的某个时间就开始关注智能卡设备,可惜一直没找到值得入手的产品。 年初知道了一种双因素认证技术叫 U2F(通用第二因素),可以通过你拥有的某个硬件设备作为用户认证时的第二因素。

U2F 设备最有名的可能是 U2F zero ,这个产品是开源的,你可以照着设计图自己焊接组装。 作者之前也在 Amazon 上卖过一些自己制作的成品。 不过成品现在是缺货状态,据作者在邮件里说新版本可能未来几个月会重新上架卖一波。

U2F

Yubikey 4 这个东西呢,大致相当于一个 U2F 设备 + 一张智能卡 + 一个 OTP 设备。这其中我们主要使用的可能是 U2F 功能和智能卡的功能。

首先是 U2F 的功能。这个东西的工作原理可以从 Yubico 提供的白皮书里摘两张图来理解。

注册U2F设备

使用U2F设备验证用户身份

简单来说,U2F 设备除了是个硬件装置以外,与 Authy app 或者 Google Authenticator app 并没有什么实质性区别。因此使用方式也是类似的:在登录支持的帐号服务(例如 Google 帐号)后,在安全设置里绑定你手头的设备就可以了;在此之后,需要使用二次验证的时候你都可以使用绑定 Yubikey 来验证。在验证时,需要将 Yubikey 插入 USB 口,指示灯亮起之后轻触感应按钮。更详细的设置介绍,可以访问在 Yubikey 包装上印制的网址来查看。

GPG 智能卡

另一种用途是 GPG 智能卡。Yubikey 4 拥有三个密钥位,可以分别存储用于签名、验证、加密三种用途的密钥。详细的设置方法参考这篇《可能是最好的 Yubikey + GPG/SSH 智能卡教程》。如果你使用 Linux 系统,参考这篇《Yubikey Guide》。 下面说一下 macOS 上需要注意的要点。

  • 如果你使用 GPGTools,那么不需要在 .bashrc.zshrc 等处加入 eval $(gpg-agent --daemon) 类似的语句,因为 GPGTools 会自动启动 gpg-agent。

  • 将三种用途的子密钥导入 Yubikey 之后,请通过密钥服务器发送你的公钥,导出你的所有私钥,然后从机器上删除这些私钥。

  • 将 Yubikey 插入机器后,运行 gpg --card-status 可以查看到智能卡的信息,此时如果拔出 Yubikey 再运行 gpg --list-secret-keys,会看到还是显示有你的私钥,例如这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    
    $ gpg --list-secret-keys
    /Users/xxx/.gnupg/secring.gpg
    -------------------------------
    sec#  4096R/08B738B8 2016-04-06
    uid                  Joker Qyou <Joker.Qyou@gmail.com>
    ssb>  4096R/E330A343 2016-04-06
    ssb>  4096R/8C6D776B 2017-04-14
    ssb>  4096R/9F07275B 2017-04-14
    

    但其实私钥已经不存在于你机器上,sec 后面的 # 表示这个只是个存根,你可以理解为一个指向智能卡的指针。

使用密钥时强制请求用户交互

GPG 在解开智能卡后的一段时间内,可以不需要用户输入智能卡密码就进行相应操作,例如 ssh 认证或给文件/消息签名。这在大部分时候都很方便,然而缺点就是软件在进行一些操作的时候,用户可能不会注意到。甚至可能出现软件在你不知情时对文件进行了签名的情况。虽然 Yubikey 4 有一个 LED,但在进行密钥操作时闪烁的时间是很短的,大概在一秒左右。

Yubikey 4 其实是支持几种不同的 touch policy 的。所谓 touch policy 就是保存在卡上的一个设置项,可以指定在调用密钥时必须同时要有用户交互,也就是接触一下卡上的触摸区域。touch policy 可以针对三个密钥分别设置,主要有这三个等级:ONOFFFIXED。其中 OFF 表示不需要用户交互,是默认等级;ON 表示开启,每次在调用密钥进行操作时,Yubikey 上的 LED 会持续闪烁,等待用户接触触摸区域,如果 15 秒内没有用户交互,操作将会失败;FIXED 表示开启这个设置项,并且不允许关闭,除非相应的密钥被替换(导入或重新生成)。

Yubico 提供了一个开源命令行工具 ykman 可以进行这个设置。在 macOS 下使用 brew install ykman 来安装。

安装好之后,插入你的 Yubikey,使用 ykman openpgp info 来查看当前的 touch policy。

要修改某个 key 的 touch policy,使用 ykman openpgp set-touch KEY POLICY 来设置。KEY 的可选值是 autencsig,分别对应验证、加密、签名三种用途的密钥;POLICY 可以是 ONOFFFIXED等级别。

个人建议对 sigaut 开启 FIXED 级别的设置。需要注意的是:如果你对密钥进行续期操作,则需要重新将子密钥倒入 Yubikey 的对应密钥槽,这是一个覆盖操作。此时对应密钥的 touch policy 会重置为 OFF,你将需要视自己的需求进行重新设置。

参考

其他一些 Yubikey 的教程参考:

可编程槽与静态密码

另外还有一个可能很少人使用的功能。Yubikey 带有两个可编程的槽(configuration slot),这两个槽与智能卡功能、U2F 功能都是分离的。第一个槽的触发方式是短按感应按钮,第二个槽的触发是靠长按,大约按住 3 秒以上。

如果你将 Yubikey 插入电脑,然后打开一个编辑器,短按感应按钮,会看到 Yubikey 输出了一个一次性密码(OTP),这是第一个槽的功能。Slot 1 在出厂时被初始化为 Yubico OTP 模式。Slot 2 是被留空的,可以自由设置。

我个人使用密码管理软件来管理所有的帐号密码,因此数据库的主密码就成了一个问题。之前主密码都被设置为易于记忆(因为遗失主密码就等于遗失所有帐号密码),现在可以通过 slot 2 来将密码管理软件的数据库主密码存储起来(配置为 static password 模式),通过 Yubikey 来输入,不需要自己每次手打了,因此可以随意设置非常复杂的密码。这个功能可以通过 Yubico 提供的设置工具 Yubikey personalization tool 来实现。