前不久入手了一块 Yubikey,主要是用来为日常的账号做二次验证用。不过 Yubikey 除了用作二次验证的物理设备之外还可以充当智能卡,往里面放密钥。现在 Yubikey 不仅支持 RSA,还支持 ECC ,感觉拿来做日常加密签名还是不错的。
不过本人环境现在主要是 Windows,按官方文档在 Windows 下安装的 Gpg4win 在生成 ECC 密钥的时候会出现以下警告:

warning: lower 3 bits of the secret key are not cleared

在网站搜了一遍之后似乎是密钥的低3位需要清零来保证它是8的倍数,避免被攻击。
(参考网址:https://crypto.stackexchange.com/questions/12425/why-are-the-lower-3-bits-of-curve25519-ed25519-secret-keys-cleared-during-creati
不过解决方案尚未查到,只能规避,不在 Windows 环境下生成密钥。
所以密钥是在 WSL2(Debian) 下生成,然后将密钥导入 Yubikey 是在 Windows 下完成的。

安装GnuPG

https://gnupg.org/download/index.html
Windows 和 WSL2 下都要装。Windows 就装 Gpg4win,WSL2 下就用 apt 安装。

# apt install gpg

生成密钥

Windows 的硬盘会被挂载到 WSL2 下的 /mnt 目录下,为了在 Windows 下可以获取成生的密钥,这里以 D 盘为例,在 /mnt/d 目录下生成密钥。

# mkdir -p /mnt/d/gpg
# cd /mnt/d/gpg
# gpg --full-gen-key

按照提示生成密钥即可,我在 2.2.27 版本下没有看到有 ECC 密钥生成的选项,需要进到专家模式才可以,也许新版会默认有。
专家模式用 --expert 选项开启。

# gpg --expert --full-gen-key

查看生成的密钥

公钥用小写的 -k 选项查看。

# gpg -k

私钥用大写的 -K 选项查看。

# gpg -K

分别生成加密、签名、验证密钥

用上面一步查到的密钥 ID 作为参数执行以下命令

# gpg --edit-key [密钥 ID]

然后会进入到 gpg 的交互模式,输入addkey

gpg> addkey

加密和签名的密钥都没有难度,按提示操作即可。
验证密钥需要在专家模式下操作:

# gpg --expert --edit-key [密钥 ID]

在这里选择 11,自定义密钥用途。

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
Your selection? 11

默认会带签名功能,先输入 A 把验证功能开启:

Possible actions for this ECC key: Sign Authenticate
Current allowed actions: Sign

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? A

然后输入 S 把签名功能关闭:

Possible actions for this ECC key: Sign Authenticate
Current allowed actions: Sign Authenticate

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? S

最后是 Q 完成:

Possible actions for this ECC key: Sign Authenticate
Current allowed actions: Authenticate

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? Q

最后查看一下密钥,看看是不是三类密钥都有了:

# gpg -K --keyid-format LONG
----------------------------------------------
sec   ed25519/XXXXXXXXXXXXXXXX 2022-04-21 [SC]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid                 [ultimate] xxx <xxx@xxx.com>
ssb   cv25519/XXXXXXXXXXXXXXXX 2022-04-21 [E]
ssb   ed25519/XXXXXXXXXXXXXXXX 2022-04-21 [S]
ssb   ed25519/XXXXXXXXXXXXXXXX 2022-04-21 [A]
----------------------------------------------

生成吊销证书

万一密钥泄漏可以通过吊销证书使密钥无效化。生成吊销证书以备不时之需。

# gpg --output revoke.asc --gen-revoke [密钥 ID]

导出和导入密钥

密钥是在 WSL2 下生成的,需要在 Windows 上导入一遍。顺便导出密钥可以做个备份。
导出:

# gpg --armor --output public.asc --export [密钥 ID]
# gpg --armor --output private.asc --export-secret-keys [密钥 ID]

看到一些教程还会用 --export-secret-sub-keys 单独导出子私钥,查了一遍官方文档,官方文档不推荐这样做,除非你是真的只想单独导出子私钥。

导入(在 Windows 上):

gpg --import public.asc
gpg --import private.asc

还看到一些文章说重新导入用 --allow-secret-key-import 选项导入私钥,其实不用,--import 就行。
--allow-secret-key-import 已经没有用了,这里摘抄一下官方文档的说明:

--allow-secret-key-import
This is an obsolete option and is not used anywhere.

将密钥写入 Yubikey

Yubikey 官方文档有非常详细的说明,不在这里赘述。Yubikey 万一更新换代可能方法会变得不一样,还是时常查看官方文档的好。
https://developers.yubico.com/PGP/

写入完成之后可以在本地删除私钥了(公钥不要删)。

gpg --delete-secret-key [密钥 ID]

之后再查看私钥的时候会发现变成下面这个样子:

# gpg -K --keyid-format LONG
----------------------------------------------
sec#   ed25519/XXXXXXXXXXXXXXXX 2022-04-21 [SC]
       XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid                 [ultimate] xxx <xxx@xxx.com>
ssb>   cv25519/XXXXXXXXXXXXXXXX 2022-04-21 [E]
ssb>   ed25519/XXXXXXXXXXXXXXXX 2022-04-21 [S]
ssb>   ed25519/XXXXXXXXXXXXXXXX 2022-04-21 [A]
----------------------------------------------

对比一下上面前几节的输出,你会发现 sec 后面多了个 #,ssb 后面多了个 >
# 的意思就是密钥(这里是主私钥)不在这台电脑上,> 的意思是密钥(这里是子私钥)指向了智能卡。

在移动到卡之后就不能再拔卡使用了,除非你在本机上彻底删除这种指向关系,可以在C:\Users\[用户名]\AppData\Roaming\gnupg\private-keys-v1.d目录下把所有文件都删除,拔卡,再重新导入一遍公私钥即可。

最后修改:2022 年 04 月 25 日
如果觉得我的文章对你有用,请随意赞赏