时隔接近一年,我终于拿到了 YubiKey。

开始

coupon.png

在 2022 年 9 月底,Yubico 跟 Cloudflare 搞了个打骨折的活动,使用 Cloudflare 帐户即可申请优惠码,可以用最低 10 美元的价格购买 YubiKey 5/5C NFC(总共最低买 2 个,最多 10 个 后来玩不起了,限制最多买 4 个)。为了降低运费成本(?),我找到了一家灵车转运然后下单,开启了我的折磨。

2023 春节都过完了,我还是没有收到。由于是平邮,无法查到国内段的信息,去邮局问了一下,他们表示过了这么久大概率是不会有了,一般会按地址直接上门投递,如果地址写得不够详细(比如我就只写到了楼栋单元号,没写到门牌号)就会退回,对此我只能说下回注意了。

本想着东西转运去了火星,认栽算了,结果到了五月底的一天早上,刚醒来坐在床上的我看了眼手机,发现收到了灵车转运包裹入库的邮件,图片正是那个 YubiKey 包裹,只不过上面多出了防疫的盖章,属于是去中国旅游回来了。

不敢再次直发中国,商量了一下之后发给了网友随身转运,总算是拿到了 YubiKey。

配置

我是在 Windows 上完成的 YubiKey 本身的配置,如果是在 macOS 或是在 Linux 上,方法会有差异。首先推荐阅读 YubiKey-Guide,其次是 docs.yubikey.wiki。ArchWiki 和 YubiKey 官方文档也有用,这个文档 我没派上用场,YubiKey-GPG-SSH-guide 也可以作为参考。

YubiKey

FIDO2 就一个 PIN,PIV 有一个 PIN 和 PUK,还有一个 Management Key,下载安装一个 YubiKey Manager,图形界面,都可以在上面设置好。OTP 建议将配置切换到长按(3 秒),让短按配置为空,这样更安全,避免误触填充。

安装一个 Yubico Authenticator,即可按 docs.yubikey.wiki 里描述的方法添加 steam 之类的两步验证码,但是总共只能存 32 个。

可以通过 ykman openpgp keys set-touch [aut|sig|dec] on 来设置要求每次在认证/签名/加密时必须触摸 YubiKey,详见 YubiKey-Guide 的 Require touch。

使用 gpg-connect-agent "scd serialno" "learn --force" /bye 即可在同一台设备上进行主用与备用 YubiKey 之间的切换,参考 YubiKey-Guide 的 Using Multiple Keys。

GPG

针对这部分,官方文档 写得很不错,可以直接照做。首先得有一个 GPG Key,如果没有就照文档生成一个,我是已经有了,只不过不带 [A] 的认证 sub-key,照着文档加一个,之后 SSH 会有用。勤用 gpg -k / gpg -K 查看 key 和 gpg --armor --export-secret-keys $KEYID > gpg.key 备份 key,多备份总是好的,不过一定要注意备份的存储安全。$KEYID 换成自己 GPG key 的 id 或是用户名(用 " 括住),或者一开始就按 YubiKey-Guide 的 Master key 结尾部分执行

$ export KEYID=

设置变量使用。

gpg -k / gpg -K 如果看见有个 unknown,需要 gpg --edit-key $KEYID 然后 trust 修改信任,输入 5 (Ultimate) 然后确认退出即可解决。

使用 gpg --card-status 检查 YubiKey 状态,gpg --edit-card 开始编辑 YubiKey GPG 信息,输入 admin 解锁管理命令。

Reader ...........: Yubico YubiKey OTP FIDO CCID 0
Application ID ...: ***
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: ***
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......: 
URL of public key : [not set]       // 公钥下载链接,比较重要,使用 url 修改
Login data .......: [not set]
Signature PIN ....: forced      // 每次签名要求 PIN,使用 forcesig 修改
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 6
KDF setting ......: on      // KDF 方式存储 PIN,只有在导入 Key 前才能用 kdf-setup 开启
UIF setting ......: Sign=on Decrypt=on Auth=on
Signature key ....: ***
      created ....: [DATE]
Encryption key....: ***
      created ....: [DATE]
Authentication key: ***
      created ....: [DATE]
General key info..:
pub  rsa2048/*** [DATE] [NAME] <[EMAIL]>
sec>  rsa2048/***  created: [DATE]  expires: [DATE]
                                card-no: ***
ssb>  rsa2048/***  created: [DATE]  expires: [DATE]
                                card-no: ***
ssb>  rsa2048/***  created: [DATE]  expires: [DATE]
                                card-no: ***

使用 gpg -o pubkey.gpg --armor --export $KEYID 导出公钥,找个地方放上去,我用的是 GitHub Gist,把源文件链接填进上面 的 url,之后把 YubiKey 插上新设备配置的时候会有用。

passwd 修改用户密码、管理密码和解锁用户密码的重置码。最好不要搞错管理密码,默认重试机会只有三次,用完就锁定了,只能 factory-reset,没有别的办法,所以备份 GPG key 很重要。如果想(在还没锁的前提下)增加重试次数,可以执行 ykman openpgp access set-retries 3 4 5 -f -a YOUR_ADMIN_PIN,这样会修改为用户密码 3 次,重置码 4 次,管理密码 5 次。[文档]

导入到 YubiKey 之前一定要注意备份(重点值得复读),导入成功后必须恢复备份才能将相同的 GPG key 再次导入到下一把 YubiKey。导入操作按官方文档来就行,小心不要把 sub-key 导入错了 slot。

Windows 10

Windows 上稍微有些麻烦,我是 2019 LTSC 钉子户,没有什么 Windows Store 和 WSL。我安装了这三个软件:Git for WindowsGpg4win 和拿来当终端的 Cygwin。文件传输可以用 WinSCP,电子邮件可以用 Thunderbird。Git for Windows 安装时可以选择 Use external OpenSSHUse the native Windows Secure Channel library

Gpg4win

上来还是常规操作,gpg --card-status 检查状态,gpg --edit-card 然后 fetch 导入公钥,quit 退出来 gpg --edit-key $KEYID 然后 trust 修改信任,这就算完成了。

Cygwin

先右键标题栏进 Options - Text,调整 Locale 和 Character set 为 en_US UTF-8。

然后整个 zsh(不用的可以略过),需要在安装 Cygwin 程序时选择 zsh,如果用 Oh My Zsh 还得加上 git,因为它不支持调用系统的。装完之后需要调整快捷方式的属性为 C:\cygwin64\bin\mintty.exe -i /Cygwin-Terminal.ico /bin/zsh --login,zsh 和 Oh My Zsh 就装好了。

可以在 ~/.zshrc 中添加

export PATH="/cygdrive/c/Program Files/Git/cmd:$PATH"

使用系统的 Git,更新 Oh My Zsh 的时候再注释掉。

使用 Cygwin 安装程序安装 vimssh-pageant (不会用 vim 就去装别的),然后在 ~/.bashrc~/.zshrc 末尾添加 eval $(/usr/bin/ssh-pageant -r -a "/tmp/.ssh-pageant-$USERNAME")

SSH Authentication to GitHub Using a YubiKey on Windows 操作,创建 %APPDATA%\gnupg\gpg-agent.conf

enable-putty-support
enable-ssh-support
use-standard-socket
default-cache-ttl-ssh 60
max-cache-ttl-ssh 120
default-cache-ttl 60
max-cache-ttl 120
pinentry-program "C:\Program Files (x86)\Gpg4win\bin\pinentry.exe"

然后重启

gpg-connect-agent killagent /bye
gpg-connect-agent /bye

使用 ssh-add -L测试,成功即会输出 SSH key,这时应该就能用了。

另外可以为鼠标右键菜单添加一个 Cygwin here,如果用原版 bash 可以直接从 Cygwin-Bash-Here 下载 reg 执行。我是在此基础上做的修改版,适用于 zsh,贴进文本文件然后修改扩展名运行就可以了。

Install Cygwin-zsh-Here (x64).reg

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\Background\shell\cygwin_zsh_here]
@="Cygwin &zsh Here"
"Icon"="\"C:\\cygwin64\\bin\\mintty.exe\""

[HKEY_CLASSES_ROOT\Directory\Background\shell\cygwin_zsh_here\command]
@=hex(2):22,00,43,00,3a,00,5c,00,63,00,79,00,67,00,77,00,69,00,6e,00,36,00,34,\
  00,5c,00,62,00,69,00,6e,00,5c,00,6d,00,69,00,6e,00,74,00,74,00,79,00,2e,00,\
  65,00,78,00,65,00,22,00,20,00,2d,00,2d,00,64,00,69,00,72,00,20,00,22,00,25,\
  00,56,00,22,00,20,00,2d,00,65,00,20,00,2f,00,62,00,69,00,6e,00,2f,00,65,00,\
  6e,00,76,00,20,00,43,00,48,00,45,00,52,00,45,00,5f,00,49,00,4e,00,56,00,4f,\
  00,4b,00,49,00,4e,00,47,00,3d,00,31,00,20,00,2f,00,62,00,69,00,6e,00,2f,00,\
  7a,00,73,00,68,00,20,00,2d,00,2d,00,6c,00,6f,00,67,00,69,00,6e,00,00,00


[HKEY_CLASSES_ROOT\Directory\shell\cygwin_zsh_here]
@="Cygwin &zsh Here"
"Icon"="\"C:\\cygwin64\\bin\\mintty.exe\""

[HKEY_CLASSES_ROOT\Directory\shell\cygwin_zsh_here\command]
@=hex(2):22,00,43,00,3a,00,5c,00,63,00,79,00,67,00,77,00,69,00,6e,00,36,00,34,\
  00,5c,00,62,00,69,00,6e,00,5c,00,6d,00,69,00,6e,00,74,00,74,00,79,00,2e,00,\
  65,00,78,00,65,00,22,00,20,00,2d,00,2d,00,64,00,69,00,72,00,20,00,22,00,25,\
  00,56,00,22,00,20,00,2d,00,65,00,20,00,2f,00,62,00,69,00,6e,00,2f,00,65,00,\
  6e,00,76,00,20,00,43,00,48,00,45,00,52,00,45,00,5f,00,49,00,4e,00,56,00,4f,\
  00,4b,00,49,00,4e,00,47,00,3d,00,31,00,20,00,2f,00,62,00,69,00,6e,00,2f,00,\
  7a,00,73,00,68,00,20,00,2d,00,2d,00,6c,00,6f,00,67,00,69,00,6e,00,00,00

Uninstall Cygwin-zsh-Here (x64).reg

Windows Registry Editor Version 5.00

[-HKEY_CLASSES_ROOT\Directory\Background\shell\cygwin_zsh_here]

[-HKEY_CLASSES_ROOT\Directory\shell\cygwin_zsh_here]

WinSCP

配置好了上面这部分之后,基本上 WinSCP 就能直接用,没啥好说的。

Thunderbird

需要注意一下 Thunderbird for Windows 的安装,由于 Gpg4win 并不分 32/64-bit 安装包,大概是默认安装情况下的系统环境 PATH 上有些问题,我也不知道怎么配置才能用,导致 64-bit Thunderbird 调用的 GPG 库对不上,然后就没法解密邮件。解决办法是下载安装 32-bit 的 Thunderbird,之前安装的 64-bit Thunderbird 大概就得先卸载掉。这点是从 Canokey 的讨论群里偷窥来的 [Thunderbird:OpenPGP:Smartcards - MozillaWiki]

对于 Thunderbird 配置,还是看 这篇 MozillaWiki,需要进 about:config 修改 mail.openpgp.allow_external_gnupg。如果是从已经配置好的设备上直接打包导出 Thunderbird 数据然后再导入进来就更方便了,应该就能直接用。

Android

我用的是 Android 11,如果浏览器用 Chrome/Brave 基本就支持 WebAuthn。我一直在用 F-Droid 上的 Fennec,结果它没法用,换成官方的 Firefox Android 就可以了。访问 Yubico Demonstration Site 即可检查浏览器的支持情况。

对于 GPG,虽然 OpenKeychain 不再活跃更新,但我不知道有什么别的可以选。同样在 SSH 上,TermBot 是基于 ConnectBot 修改的支持 OpenPGP cards 的 SSH 客户端,还能用,但它已经两年没更新了。装了这俩东西后,还是常规操作,进 OpenKeychain 读 YubiKey,让它从 url 导入公钥。在 TermBot 里添加主机,修改 Use pubkey authentication,测试连接一下,应该就能用了。

Linux

此处我用的是 Fedora 38 Gnome,WebAuthn 同样无需配置即可使用(自带 Firefox)。GPG 需要稍微配置一下,默认会遇到

$ gpg --card-status    
gpg: selecting card failed: Service is not running
gpg: OpenPGP card not available: Service is not running

可以按 Fedora 论坛的 这个帖子 做。

~/.gnupg/scdaemon.conf

pcsc-shared
pcsc-driver libpcsclite.so.1

~/.gnupg/gpg-agent.conf 参考 YubiKey-Guide 的 Create configuration。

$ cd ~/.gnupg

$ wget https://raw.githubusercontent.com/drduh/config/master/gpg-agent.conf

$ grep -ve "^#" gpg-agent.conf
enable-ssh-support
default-cache-ttl 60
max-cache-ttl 120
pinentry-program /usr/bin/pinentry-curses

此处可以修改为 pinentry-program /usr/bin/pinentry-gnome3 设置弹出图形界面的输入密码提示。

使用 sudo / root 添加 /etc/polkit-1/rules.d/10-pcsc-custom.rules,将 myusername 修改为系统的用户名。

polkit.addRule(function(action, subject) {
    if (action.id == "org.debian.pcsc-lite.access_pcsc" &&
        subject.user == "myusername") {
            return polkit.Result.YES;
    }
});

polkit.addRule(function(action, subject) {
    if (action.id == "org.debian.pcsc-lite.access_card" &&
        action.lookup("reader") == 'Yubico YubiKey OTP+FIDO+CCID 00 00' &&
        subject.user == "myusername") {
            return polkit.Result.YES;
    }
});

然后一顿重启操作

$ sudo systemctl restart polkit
$ sudo systemctl restart pcscd
$ gpgconf --kill gpg-agent
$ gpg-connect-agent updatestartuptty /bye

在这之后使用 gpg --card-status 检查,应该就能用了。然后就是常规操作,gpg --edit-card 然后 fetch 导入公钥,quit 退出来 gpg --edit-key $KEYID 然后 trust 修改信任。

针对 SSH,参考 YubiKey-Guide 的 Replace agents,在 shell 的 rc 文件(~/.bashrc / ~/.zshrc)中添加

export GPG_TTY="$(tty)"
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent

重开终端,使用 ssh-add -L 检查是否有读到 SSH 公钥,然后就可以与保存了这个公钥的主机进行 SSH 链接了。

对于 Thunderbird,还是看 这篇 MozillaWiki,需要进 about:config 修改 mail.openpgp.allow_external_gnupg。如果是从已经配置好的设备上直接打包导出 Thunderbird 数据然后再导入进来就更方便了,应该就能直接用。

GitHub

首先可以参考 Generating a new GPG key,说简单点就是用 gpg --armor --export $KEYID 输出 pubkey(如果设置了独立的 [S] subkey 就要转而输出它),然后贴到 GitHub SSH and GPG keys 设置中。SSH key 就直接把 ssh-add -L 的输出内容贴进去保存,Key type 选择 Authentication Key

然后参考 Telling Git about your signing key,把 git 设置一下。最后通过随便糊个 commit 上传,或是通过 SSH 链接 clone 自己的 private repo 测试是否成功。

使用

由于 YubiKey 本身不是什么存储设备,所以不用搞什么安全弹出,想拔就拔,不会有问题。刚开始用的几次我都这么做了,后来去搜索看了 Reddit 才知道不需要

因为我觉得目前还是 Type-A 占普遍地位,所以我买的全是 5 而不是 5C。但是由于 YubiKey 本身做得轻薄,并不是常规 U 盘的那种完整接口设计,所以没有防呆,正反都能插进去 (草 - 中日双语),很明显插反了就没法用,所以需要注意,一般会是用大拇指握持到触摸区域。

一把 YubiKey 5 总共就有 7 个密码,如果把所有的密码都设置得一样,很明显是不安全的,还不如不买。所以我觉得买 YubiKey 的前提是有在经常使用密码管理器而且用得正确,如果还在重复使用密码或者弱密码,不如先换掉这些,比买 YubiKey 省钱且有意义。

我有准备备用的 YubiKey,所以为了区分,在 YubiKey 的背面贴上了标签,但在还没全部设置好的情况下,两把 YubiKey 放桌上,有时还是拿错,加上我设置的密码都不相同,所以就会提示密码错误。

由于 YubiKey 密码的重试次数有限,默认情况下 FIDO2 8 次,PIV 和 GPG 的三个都是 3 次,用完就会被锁定,搞不好就必须 factory-reset 重新来过,所以使用时要注意把密码输对,最好把密码存到安全的地方(比如密码管理器)防止遗忘且方便核对,输错两次就要引起格外警惕了,建议看着存好的密码慢点按。

改完 Require touch 后经常会忘记输完密码要摸 YubiKey,大概还得用比较长的一段时间才能习惯。

费劲把上百个密码管理器条目逐个登录检查一遍,最后成功套上 YubiKey 的一共也就二十个,其中微软占了五分之一。只能说 FIDO2/WebAuthn 还是不够流行,不是所有的服务都支持两步验证,从这里面挑出支持硬件 Key 的就更少了,看以后会不会有更多服务安排上。

至于 PIV,因为完全没有派上用场,所以本文基本就没有提到,有此需要的朋友请自行搜寻文档操作。

结束

如果没有 Cloudflare 合作提供的这种打骨折机会,我是不会买 YubiKey 的,毕竟成本不低,我也不是一定要它才能做什么事情。当然,目前在国内有了能用且比 YubiKey 便宜的 Canokey Pigeon(鸽子) 可以选择,购买也更方便。

YubiKey 有没有给我带来安全,我对此没有实感,但在近期确实地给我带来了不少麻烦。 至少好几天的时间没有了

最后还是用 这个经典的 xkcd 漫画 来结尾吧。

security.png

His laptop's encrypted. Drug him and hit him with this $5 wrench until he tells us the password.
- Got it.

标签: none

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。

添加新评论