精玩教程来喽~

# 前言

这篇文章主要是精玩 CanoKey,前期准备请先看 Canokey Pigeon 的初级玩法

# 开始

# FIDO2/U2F

这个功能我们用的最多的还是 WebAuthn,将 CanoKey 绑定到账号中即可,下次登录就可以完成验证

具体相关设置根据具体网站而定

常用的包括 GitHub, Cloudflare, Microsoft, Google, Twitter, Facebook 等

更多支持 FIDO2/U2F/TOTP 的网站可以参考 2FA Directory

目前 Microsoft 账户支持使用硬件密钥实现单因素登录,即无需密码直接登录,可以进入账户的其他安全选项部分进行添加。

# OpenPGP

我这里采用的是 Git 客户端自带的 gpg,因为我平常 git 提交代码签名用的多,所以直接就用 Git Bash 来操作

当然你也可以去专门搭建一个环境

我这里就简单说一下步骤,具体详情请看 2021 年,用更现代的方法使用 PGP(上)

在进行操作前建议看看上面链接的文章了解一下什么是 OpenPGP

推荐使用 Tails (boum.org) 进行密钥生成操作

系统自带 pgp 和 paper key 等工具,可以确保全程断网操作,同时此系统重启会擦除所有内容,还免去了擦除密钥的麻烦。

注:使用此系统请一定先校准系统时间,否则会导致生成的密钥无法使用!!!(踩雷大亨)

# 生成主密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
gpg --expert --full-gen-key

gpg (GnuPG) 2.3.4; Copyright (C) 2021 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(13) Existing key
(14) Existing key from card
Your selection? 11

# 推荐使用 ECC 算法

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

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

Your selection? s

# 主密钥只保留 Certify 功能,其他功能使用子密钥

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

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

Your selection? q

Please select which elliptic curve you want:
(1) Curve 25519 *default*
(2) Curve 448
(3) NIST P-256
(4) NIST P-384
(5) NIST P-521
(6) Brainpool P-256
(7) Brainpool P-384
(8) Brainpool P-512
(9) secp256k1
Your selection? 1

Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

# 主密钥永不过期即可

Real name: Editst
Email address: editst@example.com
Comment:
You selected this USER-ID:
"Editst <editst@example.com>"

# 这里按实际情况填写,注意保护自己的隐私

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

# Windnows 下会弹出窗口输入密码,注意一定要保管好!!!

gpg: revocation certificate stored as 'C:\\Users\\XXX\\AppData\\Roaming\\gnupg\\openpgp-revocs.d\\68697537A54B1F0BFC05E1D9787E848E1A98D086.rev'
public and secret key created and signed.

# 会自动生成吊销证书,注意保存到安全的地方

pub ed25519/787E848E1A98D086 2022-01-01 [C]
Key fingerprint = 6869 7537 A54B 1F0B FC05 E1D9 787E 848E 1A98 D086
uid Editst <editst@example.com>

# 生成子密钥

1
gpg --fingerprint --keyid-format long -K

可以看到目前生成的主密钥

下面是生成三个用途不同的子密钥

1
2
3
gpg --quick-add-key <fingerprint> cv25519 encr 2y
gpg --quick-add-key <fingerprint> ed25519 auth 2y
gpg --quick-add-key <fingerprint> ed25519 sign 2y

其中 fingerprint 是主密钥指纹

再次查看目前的私钥,可以看到已经包含了这三个子密钥

1
2
3
4
5
6
7
8
9
10
11
12
gpg --fingerprint --keyid-format long -K
C:\Users\XXX\AppData\Roaming\gnupg\pubring.kbx
------------------------------------------------
sec ed25519/787E848E1A98D086 2022-01-01 [C]
Key fingerprint = 6869 7537 A54B 1F0B FC05 E1D9 787E 848E 1A98 D086
uid [ultimate] Editst <editst@example.com>
ssb ed25519/055917609C9C0D7B 2022-01-01 [S] [expires: 2024-01-01]
Key fingerprint = E99F 3D15 7ACF 7E24 3DC8 FFE7 0559 1760 9C9C 0D7B
ssb ed25519/05F4A6C335157258 2022-01-01 [A] [expires: 2024-01-01]
Key fingerprint = C4B9 7EEC 4060 F856 7A4D 2956 05F4 A6C3 3515 7258
ssb cv25519/C5B8214C3AD21C6C 2022-01-01 [E] [expires: 2024-01-01]
Key fingerprint = E39E E067 3233 BD73 7ED1 15F1 C5B8 214C 3AD2 1C6C

上面生成了三种功能的子密钥(ssb),分别为加密(E)、认证(A)、签名(S), 对应 OpenPGP Applet 中的三个插槽

由于 ECC 实现的原因,加密密钥的算法区别于其他密钥的算法。

密钥 用途
加密密钥 用于加密文件和信息。
签名密钥 主要用于给自己的信息签名。
认证密钥 主要用于 SSH 登录。

# UID 设置

你可以添加多个 UID,但是删除 UID 只能采用吊销的方式

UID 作用于全局,不只作用于某个子密钥

1
gpg --quick-add-uid <fingerprint> 'Editst <editst.github@example.com>'

你也可以手动指定主 UID

1
gpg --quick-set-primary-uid <fingerprint> 'Editst <editst@example.com>'

# 导出证书

导出主密钥公钥

1
2
gpg -ao public-key.pub --export 787E848E1A98D086
#这里的指纹可以不用使用全写的

导出主密钥私钥和子密钥私钥

注意 key id 后面的!,表示只导出这一个私钥,若没有的话默认导出全部私钥。

1
2
3
4
5
gpg -ao sec-key.asc --export-secret-key 787E848E1A98D086!
# 主密钥,请务必保存好!!!
gpg -ao sign-key.asc --export-secret-key 055917609C9C0D7B!
gpg -ao auth-key.asc --export-secret-key 05F4A6C335157258!
gpg -ao encr-key.asc --export-secret-key C5B8214C3AD21C6C!

具体备份策略可以参照 2021 年,用更现代的方法使用 PGP(中)

  • 主密钥只保留一份,建议备份在一个全盘加密的 U 盘中,然后放在一个绝对安全的地方。

  • 子密钥可以复制多份,通过 U 盘导入各个设备,专密专用,日常使用推荐用智能卡(比如 Yubikey),还能免去每次输密码的麻烦

  • 撤销凭证可以和主密钥放在一起备份一份, 另外单独备份一份(这样丢失密钥,起码还可以撤销)

下面介绍配合智能卡使用子密钥

# 导入 CanoKey

注:这步是不可逆的,一但私钥导入智能卡并保存,本地私钥会被删除,无法再次恢复,因此务必确认已经正确完善备份。

将各个子密钥导入对应插槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
gpg --edit-key 787E848E1A98D086
gpg (GnuPG) 2.3.4; Copyright (C) 2021 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec ed25519/787E848E1A98D086
created: 2022-01-01 expires: never usage: C
trust: ultimate validity: ultimate
ssb ed25519/055917609C9C0D7B
created: 2022-01-01 expires: 2024-01-01 usage: S
ssb ed25519/05F4A6C335157258
created: 2022-01-01 expires: 2024-01-01 usage: A
ssb cv25519/C5B8214C3AD21C6C
created: 2022-01-01 expires: 2024-01-01 usage: E
[ultimate] (1). Editst <editst@example.com>

gpg> key 1 # 首先选中第一个子密钥

gpg> keytocard
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1 # 选择对应插槽

# 首先输入 OpenPGP 的密码,再输入 OpenPGP Applet 对应的 Admin PIN
# 之后先反选 key 1,再依次选择 key 2,key 3,重复操作即可

gpg> key 1
gpg> key 2
gpg> keytocard
Please select where to store the key:
(3) Authentication key
Your selection? 3
gpg> key 2
gpg> key 3
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2

gpg> save # 保存修改

这时再次查看 Canokey 状态,确认导入成功。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
gpg --card-status
Reader ...........: canokeys.org OpenPGP PIV OATH 0
Application ID ...: xxxxxxxxxxxxxxxxxxxxxxxxxxx
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: CanoKeys
Serial number ....: xxxxxxxx
Signature PIN ....: forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 64 64 64
PIN retry counter : 3 0 3
Signature counter : 0
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: E99F 3D15 7ACF 7E24 3DC8 FFE7 0559 1760 9C9C 0D7B
created ....: 2022-01-01 13:09:11
Encryption key....: E39E E067 3233 BD73 7ED1 15F1 C5B8 214C 3AD2 1C6C
created ....: 2022-01-01 13:09:32
Authentication key: C4B9 7EEC 4060 F856 7A4D 2956 05F4 A6C3 3515 7258
created ....: 2022-01-01 13:09:49
General key info..: sub ed25519/055917609C9C0D7B 2022-01-01 Editst <editst@example.com>
sec ed25519/787E848E1A98D086 created: 2022-01-01 expires: never
ssb> cv25519/055917609C9C0D7B created: 2022-01-01 expires: 2024-01-01
card-no: F1D0 xxxxxxxx
ssb> ed25519/05F4A6C335157258 created: 2022-01-01 expires: 2024-01-01
card-no: F1D0 xxxxxxxx
ssb> ed25519/C5B8214C3AD21C6C created: 2022-01-01 expires: 2024-01-01
card-no: F1D0 xxxxxxxx

现在可以删除掉主密钥了,请再次确认你已安全备份好主密钥。

1
gpg --delete-secret-keys 787E848E1A98D086

我这里使用的 Tails,所以直接关机即可

# 导入公钥

我们在 Tails 上操作完成后将公钥导入到日常使用的电脑中

1
gpg --import public-key.pub

然后将子密钥指向 Canokey

1
2
gpg --edit-card
gpg/card> fetch

此时查看本地的私钥,可以看到已经指向了 Canokey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gpg --fingerprint --keyid-format long -K
C:\Users\XXX\AppData\Roaming\gnupg\pubring.kbx
------------------------------------------------
sec# ed25519/787E848E1A98D086 2022-01-01 [C]
Key fingerprint = 6869 7537 A54B 1F0B FC05 E1D9 787E 848E 1A98 D086
uid [ultimate] Editst <editst@example.com>
ssb> ed25519/055917609C9C0D7B 2022-01-01 [S] [expires: 2024-01-01]
Key fingerprint = E99F 3D15 7ACF 7E24 3DC8 FFE7 0559 1760 9C9C 0D7B
Card serial no. = F1D0 xxxxxxxx
ssb> ed25519/05F4A6C335157258 2022-01-01 [A] [expires: 2024-01-01]
Key fingerprint = C4B9 7EEC 4060 F856 7A4D 2956 05F4 A6C3 3515 7258
Card serial no. = F1D0 xxxxxxxx
ssb> cv25519/C5B8214C3AD21C6C 2022-01-01 [E] [expires: 2024-01-01]
Key fingerprint = E39E E067 3233 BD73 7ED1 15F1 C5B8 214C 3AD2 1C6C
Card serial no. = F1D0 xxxxxxxx

之后可以使用 gpg 进一步配置 Canokey,可以设置 name,forcesig 等内容,同时可前往 Canokey Web Console Touch Policy 配置每次使用时是否需要触摸以及缓存时间等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
gpg --card-edit

gpg/card> admin
Admin commands are allowed

gpg/card> help
quit quit this menu
admin show admin commands
help show this help
list list all available data
name change card holder's name
url change URL to retrieve key
fetch fetch the key specified in the card URL
login change the login name
lang change the language preferences
salutation change card holder's salutation
cafpr change a CA fingerprint
forcesig toggle the signature force PIN flag
generate generate new keys
passwd menu to change or unblock the PIN
verify verify the PIN and list all data
unblock unblock the PIN using a Reset Code
factory-reset destroy all keys and data
kdf-setup setup KDF for PIN authentication (on/single/off)
key-attr change the key attribute
uif change the User Interaction Flag

tips: 我发现 Tails 上面的 gpg 是中文的,如果英文不怎么好可以在 Tails 上面先设置好

如果你使用了多个智能卡,切换后可能会因为私钥仍指向其他卡而出现问题,可以使用下面命令刷新

1
gpg-connect-agent "scd serialno" "learn --force" /bye

以上命令均转载于 https://editst.com/2022/canokey-guide/,更多详细信息可以参考原文~

# Git Commit 签名

1
git config --global user.signingkey 055917609C9C0D7B

# PIV

目前还没相关需求,更多信息请参考 https://editst.com/2022/canokey-guide/

# NDEF

这块就和 NFC 标签一样的,所以我就用手机进行写入

软件:NFC Tools PRO

# OATH

我这里是使用的 yubico-authenticator,当然你可以使用新版控制台来添加

yubico-authenticator 的好处是可以直接识别屏幕上的二维码,方便导入,不必去填写各种信息

# 后记

关于更多 OpenPGP 的使用以及更加深入的了解与使用 OpenPGP,请参考下方三篇博文

# 参考