Yubikey 教程(二)通过 Yubikey 使用 GPG 和 SSH

本文是 Yubikey 系列教程的第二篇,介绍如何安全地生成 GPG 密钥并通过 Yubikey 安全地存储和使用它。

本文大部分翻译自 https://github.com/drduh/YubiKey-Guide ,在其基础上进行了一些修改

准备工作

你需要准备:

  1. 一台可信的 Linux 计算机,我使用 Ubuntu 22.04,搭载 GnuPG 2.2.27
  2. Yubikey
  3. 离线存储设备,如 U 盘或 SD 卡,我使用的是打开了 Bitlocker 的 U 盘
  4. 如果你有旧密钥,需要对其进行一些处理
  5. 下载 gpg.conf 并拷贝到离线存储设备中

准备一台可信的计算机

@drduh 其文章中列出了风险从高到底的设备:

  1. 日常使用的系统
  2. 日常使用系统上的虚拟机(使用 virt manager、VirtualBox 或 VMware)
  3. 独立的 Debian 或 OpenBSD 安装(双系统也算)
  4. Live image,如 Debian Live 或 Tails
  5. 安全硬件/固件(Coreboot, Intel ME removed)
  6. 无网络功能的专用气隙系统(Dedicated air-gapped system)

作为个人,我们不需要也不太可能拥有专用的硬件或系统。我的建议是使用断开网络的 Ubuntu Live 或者断开网络的独立 Debian(Ubuntu) 安装。除非你有两台电脑,最好提前下载好需要的资料(比如这篇教程)并拷贝到 USB 设备中,插入电脑备用。

你需要在该计算机上安装 SmartCard daemon 以和 Yubikey 交互:

1
sudo apt-get install pcscd scdaemon pcsc-tools

处理旧密钥

如果你有旧密钥,建议将其过期时间调为最近(我调为了三天后)。我们将会对新旧密钥进行交叉签名以确认密钥的归属,所以需要先导出密钥,并存到离线存储设备中备用:

1
gpg --export-secret-keys --armor --output oldkeys.sec

虽然这样导出的密钥仍然收到密码的保护(如果你设置了),但还是建议将其放在安全的地方。

生成 GPG 密钥

以下步骤均需要在可信的 Linux 计算机上进行。

准备工作文件夹

我们需要一个不会写入到磁盘上、重启后自动抹除的目录。位于内存上的文件系统 tmpfs 满足这个要求。在 Ubuntu 22.04 上, /tmp 并不挂载于 tmpfs ,所以我们需要创建一个使用 tmpfs 的目录。

1
2
3
4
5
mkdir $TMPDIR
sudo mount -t tmpfs -o size=512M tmpfs $TMPDIR
export GNUPGHOME=$TMPDIR/gpg
sudo chown $UID:$GID $GNUPGHOME
chmod 700 $GNUPGHOME

注意:tmpfs 上的内容可能会被交换到虚拟内存中(位于磁盘上)。如果你认为有必要,可以关闭虚拟内存。

然后,将 gpg.conf 从离线存储设备复制到 $GNUPGHOME

生成主密钥和子密钥

这里基本上按照原文章生成主密钥子密钥即可。对原文补充以下几点:

  1. 可以通过该命令生成 24 位的大写字母+数字字符串:gpg --gen-random --armor 0 24 | tr '[:lower:]' '[:upper:]'
  2. 加密子密钥应当设置为永不过期

与旧密钥交叉签名

下面的命令将导入旧密钥到当前密钥环、互相签名,并检查签名结果

1
2
3
4
5
gpg --import $OLDKEYPATH
gpg --list-secret-keys
gpg --default-key $OLDKEY --sign-key $KEYID
gpg --default-key $KEYID --sign-key $OLDKEY
gpg --check-signatures

备份密钥

创建一个压缩文件,包含密钥的备份和两张吊销证书(分别用于密钥泄露和密钥丢失时的吊销)。该文件将使用刚刚生成的密钥签名,并使用 AES256 进行对称加密。请将对称加密的密码和加密的压缩文件保存到不同的安全的位置。压缩文件应当离线保存。

你应当将吊销证书保存在至少一个与私钥不同的地方。因为吊销证书是在没有私钥时使用的(私钥可以随时生成新的吊销证书),所以把吊销证书和私钥放在一起是没有意义的。

尽管吊销证书也需要妥善保存(否则攻击者可以吊销你的密钥),但其敏感性并没有私钥高,安全性要求可以适当降低。

1
2
3
4
5
6
7
8
9
mkdir $GNUPGHOME/backup
gpg --armor --export-secret-keys $KEYID > $GNUPGHOME/backup/mastersub.key
gpg --armor --export-secret-subkeys $KEYID > $GNUPGHOME/backup/sub.key
gpg --output $GNUPGHOME/backup/revoke-leak.asc --gen-revoke $KEYID
gpg --output $GNUPGHOME/backup/revoke-lost.asc --gen-revoke $KEYID
cd $GNUPGHOME/backup
zip -r ../backup.zip *
cd ../
gpg --symmetric --default-key $KEYID --sign --cipher-algo AES256 backup.zip

解密压缩文件的命令:

1
gpg --output backup.zip --decrypt backup.zip.gpg

导出公钥

Base64 格式

Base64 格式的密钥可以用于密钥交换、上传 GitHub 等:

1
2
gpg --armor --export $KEYID > new-pubkey.asc
gpg --armor --export $OLDKEY > old-pubkey.asc

Web Key Directory

WKD (Web Key Directory) 是一种分发密钥的方式。如果你的电子邮件在你自己的域名上,你可以和我一样通过 WKD 分发密钥。

执行命令 gpg --with-wkd-hash --fingerprint me@caomingjun.com (替换成你的邮箱)将给出类似的输出:

1
2
3
4
5
6
7
pub   rsa4096 2023-01-19 [C]
D3B7 BADB 80DB 1635 4171 BF47 7642 4559 FEBC F229
uid [ultimate] Cao Mingjun <me@caomingjun.com>
s8y7oh5xrdpu9psba3i5ntk64ohouhga@caomingjun.com
sub rsa4096 2023-01-19 [S] [expires: 2025-01-18]
sub rsa4096 2023-01-19 [E]
sub rsa4096 2023-01-19 [A] [expires: 2025-01-18]

其中的 s8y7oh5xrdpu9psba3i5ntk64ohouhga 是 WKD Hash。然后导出公钥到文件名为 WKD Hash 的文件:

1
gpg --no-armor --export me@caomingjun.com > s8y7oh5xrdpu9psba3i5ntk64ohouhga

该文件托管于 https://openpgpkey.caomingjun.com/.well-known/openpgpkey/caomingjun.com/hu/s8y7oh5xrdpu9psba3i5ntk64ohouhga 。支持 WKD 的应用程序(例如 Thunderbird)会自动获取该公钥。他人也可以通过 GPG 获取该公钥:

1
gpg --auto-key-locate clear,wkd --locate-keys me@caomingjun.com

根据标准,你还需要在形如 https://openpgpkey.caomingjun.com/.well-known/openpgpkey/caomingjun.com/policy 的位置托管一个 policy 文件,空文件即可。

将密钥转移到 Yubikey

这部分按照原文操作即可。如果出现类似这样的错误,说明你没有安装 SmartCard daemon ,请回去看准备环节

1
2
gpg: error getting version from 'scdaemon': No SmartCard daemon
gpg: OpenPGP card not available: No SmartCard daemon

Cleanup

进行清理前,请确保你将私钥、公钥保存到了离线存储设备!

1
2
3
sudo rm -rf $GNUPGHOME/
sudo umount $TMPDIR/
rmdir $TMPDIR

Thunderbird

你可以在 Thunderbird 上使用 Yubikey 解密或签名邮件,可以参考官方教程,虽然这是 Thunderbird 78 的教程,但是对于 102.8.0 仍然适用。

Reference

  1. Ubuntu Blog (webarchive): 创建 tmpfs
  2. @drduh 撰写的教程
  3. Gnupg Wiki: WKD (Web Key Directory)
  4. IETF Standard: WKD specs
  5. GitHub Gist: WKD Hosting
  6. Thunderbird Wiki: How to use Thunderbird 78 with smartcards

Yubikey 教程(二)通过 Yubikey 使用 GPG 和 SSH

https://blog.caomingjun.com/series/yubikey/gpg/

作者

Cao Mingjun

发布于

2023-02-25

更新于

2023-02-25

许可协议

评论