GPG 使用教程

这个教程是对原 Yubikey 使用教程的补充。

安装软件

Linux

sudo apt install gpg

Debian 下的 GUI 工具叫 seahorse

Mac

以下三选一

brew install gpg               # 和 Linux 一样的 CLI 界面
brew install gpg-suite         # GUI,但是附带的 mail 功能要收费
brew install gpg-suite-no-mail # 没有 mail 功能的全免费版本

创建各种 GPG Key

为了绝对安全,以下功能请断网操作。话是这样说,但不断网其实也没啥事儿啦。

生成主密钥

懒人版

我们可以照着向导,一步一步生成

gpg --gen-key
gpg (GnuPG/MacGPG2) 2.2.40; Copyright (C) 2022 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.

注意:使用 “gpg --full-generate-key” 以获得一个全功能的密钥生成对话框。

GnuPG 需要构建用户标识以辨认您的密钥。

真实姓名: # 你自己随便输入,比如 UserName
电子邮件地址: # 你自己随便输入,比如 test@gmail.com
您选定了此用户标识:
    “UserName <test@gmail.com>”

更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)? O
我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘
、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数
发生器有更好的机会获得足够的熵。

gpg: 目录 ‘/Users/USERNAME/.gnupg/openpgp-revocs.d’ 已创建
gpg: 吊销证书已被存储为 ‘/Users/USERNAME/.gnupg/openpgp-revocs.d/XXXXXXXX.rev’
公钥和私钥已经生成并被签名。

pub   rsa3072 2022-11-20 [SC] [有效至:2024-11-19]
      XXXXXXXX
uid                      UserName <test@gmail.com>
sub   rsa3072 2022-11-20 [E] [有效至:2024-11-19]

于是我们就得到了公钥和主密钥,还有吊销证书。

一步一步来做

在用懒人版的时候,屏幕上提示说可以用 gpg --full-generate-key 来自定义所有东西。那么,一起试试:

gpg --full-generate-key
gpg (GnuPG/MacGPG2) 2.2.40; Copyright (C) 2022 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.

请选择您要使用的密钥类型:
   (1) RSA 和 RSA(默认)
   (2) DSA 和 Elgamal
   (3) DSA(仅用于签名)
   (4) RSA(仅用于签名)
(14)卡中现有密钥
您的选择是?

选默认

RSA 密钥的长度应在 1024 位与 4096 位之间。
您想要使用的密钥长度?(3072) 

直接 4096 吧~好像后续也没啥问题

请求的密钥长度是 4096 位
请设定这个密钥的有效期限。
         0 = 密钥永不过期
      <n>  = 密钥在 n 天后过期
      <n>w = 密钥在 n 周后过期
      <n>m = 密钥在 n 月后过期
      <n>y = 密钥在 n 年后过期
密钥的有效期限是?(0) 

额,如果你洁癖或者有强迫症的话,可以设定一个时间,但无所谓反生成好后可以随便改。我……怕忘记续命,就不设置过期时间了。

这些内容正确吗? (y/N) 

Yes!

GnuPG 需要构建用户标识以辨认您的密钥。

真实姓名:

哦随便啦,又不是查户口。但是说必须至少 5 个字符?

电子邮件地址:

随意啦~

您选定了此用户标识:
    “Test <test@gmail.com>”

更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)?

然后会弹出来个对话框让你输入个密码。这个密码是用来保护你的 key 的。后续只有提供这个密码,才能对你的密钥进行修改,例如添加子密钥、延期,等等。

我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘
、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数
发生器有更好的机会获得足够的熵。
gpg: 吊销证书已被存储为 ‘/Users/USERNAME/.gnupg/openpgp-revocs.d/XXXXXXXX.rev’
公钥和私钥已经生成并被签名。

pub   rsa4096 2022-11-20 [SC]
      XXXXXXXX
uid                      Test <test@gmail.com>
sub   rsa4096 2022-11-20 [E]

可以看到,和上面一样,生成了公钥、主密钥和吊销证书。

生成子密钥

刚才生成的是主密钥。一般来说,主密钥有仨用途,一个是生成用于干活的子密钥们,一个是吊销用于干活的子密钥们,一个是躺着睡大觉。

gpg --expert --edit-key XXXXXXXX
gpg (GnuPG/MacGPG2) 2.2.40; Copyright (C) 2022 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.

私钥可用。

sec  rsa4096/AAAAAAAAAAAAAAAA
     创建于:2022-11-20  有效至:永不       可用于:SC  
     信任度:绝对        有效性:绝对
ssb  rsa4096/BBBBBBBBBBBBBBBB
     创建于:2022-11-20  有效至:永不       可用于:E   
[ 绝对 ] (1). Test <test@gmail.com>
gpg> addkey
请选择您要使用的密钥类型:
   (3) DSA(仅用于签名)
   (4) RSA(仅用于签名)
   (5) ElGamal(仅用于加密)
   (6) RSA(仅用于加密)
   (7) DSA(自定义用途)
   (8) RSA(自定义用途)
  (10) ECC(仅用于签名)
  (11) ECC(自定义用途)
  (12) ECC(仅用于加密)
  (13) 现存的密钥
(14)卡中现有密钥

我们需要分别选

(4) RSA(仅用于签名)=> 对应 签名 (S, Sign)
(6) RSA(仅用于加密)=> 对应 加密 (E, Encryption)
(8) RSA(自定义用途)=> 对应 认证 (A, Authenticate)

后续的步骤和前面生成主密钥的步骤其实差不多。

完事儿后,保存退出。

gpg> save

生成吊销凭证

吊销凭证的作用是,当你不慎把自己的私钥泄漏之后,可以将这个对应的吊销凭证公之于众,说「这个 key 已经不能用啦」。于是其他人便不再信任这个 key 产生的任何东西。

其实在你生成主密钥的时候,就已经生成好一个吊销凭证了。这里只是记录一下怎么自己再生成一个。

gpg --ken-revoke XXXXXXXX

备份出来!

不然哭都没机会!一旦导入到 YubuKey 里面就再也拿不出来了!

gpg --armor --export --output main-public-key.txt
gpg --armor --export-secret-keys --output main-private-key.txt
gpg --armor --export-secret-subkeys --output sub-private-key.txt

GUI 操作

所以为啥要拿 CLI 难为自己啊啊啊啊啊啊啊啊!都有 GUI 了,用它不香么!

以下操作都是在 Mac 的 GPG Keychain 里面进行的(gpg-suite 套件内容之一)。如果你是 Linux,应该也有相似软件的。

生成主密钥

点击主界面的「新建」,输入信息,点击「高级选项」,密钥类型选「RSA 和 RSA(默认)」,长度选 4096,过期时间随意。

生成子密钥

在密钥列表(其实是公钥列表)里面双击刚刚生成出来的主密钥,在「子密钥」里面点加号,然后分别选几种用途,过期时间随意,就好啦~

生成吊销凭证

在密钥列表里面右键,然后选「吊销」即可。

备份出来!

右键-导出,然后选择「在导出的文件中加入密钥」

将 GPG Key 导入 YubiKey 中

YubiKey 的初始密码

对于 GPG,有三个密码:

  • PIN:6 位,默认是 123456,是设备的最常用密码。一般来说,签名啊、鉴权啊,需要用到密码的时候,输入的都是这个密码。这个密码输入错超过 3 次后需要输入 Reset Code。
  • Admin PIN:必须不少于 8 位,默认是 12345678,执行设备管理动作的时候需要输入的密码。一般来说,设置姓名信息、导入私钥之类的时候需要输入的都是这个密码。这个密码输入错 3 次,或者设置时长度少于 8 位,都将导致设备锁定,只能物理重置。
  • Reset Code:好像相当于某些 PUK 码。看起来是用来重置 PIN 码输入错误次数的。这个密码输出错超过 3 次后设备锁定,只能物理重置

所以为了安全,我们需要将这些默认密码改掉。

gpg --card-edit

Reader ...........: Yubico YubiKey OTP FIDO CCID
Application ID ...: D0000000000000000000000000000000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 000000000
Name of cardholder: [未设定]
Language prefs ...: [未设定]
Salutation .......: 
URL of public key : [未设定]
Login data .......: [未设定]
Signature PIN ....: 非强制
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 1
KDF setting ......: off

然后输入

gpg/card> admin
管理员命令可用

然后我们来设置密码

gpg: 检测到 OpenPGP 卡,号码为 D0000000000000000000000000000000

1 - change PIN           => 对应设置 6 位 PIN 密码
2 - unblock PIN          => 我没用过
3 - change Admin PIN     => 设置管理密码
4 - set the Reset Code   => 我也没用过
Q - quit

反正……设置一下就是了。注意位数即可。默认密码?往上面翻翻~

我看好像 YubiKey Manager 里面也有设置的地方,不知道是不是同一个东西。

然后可以再根据自己喜好设置点个人信息。

将 Key 导入到 YubiKey 中

先问自己一句:前面生成的 key,备份了没?要连带着私钥一起备份啊~

gpg --edit-key

gpg (GnuPG/MacGPG2) 2.2.40; Copyright (C) 2022 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.

私钥可用。

sec  rsa4096/0000000000000000
     创建于:2022-11-20  有效至:永不       可用于:SC  
     信任度:绝对        有效性:绝对
ssb  rsa4096/0000000000000000
     创建于:2022-11-20  有效至:永不       可用于:E   
ssb  rsa2048/1111111111111111
     创建于:2022-11-20  有效至:永不       可用于:S   
ssb  rsa2048/2222222222222222
     创建于:2022-11-20  有效至:永不       可用于:E   
ssb  rsa2048/3333333333333333
     创建于:2022-11-20  有效至:永不       可用于:A   
[ 绝对 ] (1). Test <test@gmail.com>

到这里再问自己一句:确定备份了吧?

OK。我们来看一下。

  • 第一行 sec 是个公钥
  • 第二行 ssb 可用于 E,是你的主密钥
  • 第三行到后面,是你的私钥,分别可用于 S、E 和 A

首先输入

gpg/card> key 2

这时候,rsa2048/1111111111111111 前面会多一个星号,表示选中了。

然后输入

gpg/card> keytocard

会将这个 key 导入 YubiKey 里面。可能还会问你需要导入啥东西,这时候根据 Key 的类型选对应东西即可。最后还需要输入 Admin PIN 来「解锁」。

最后最后,输入

gpg/card> save

保存,然后退出,拔卡~

再来检测一下

gpg --card-edit
gpg (GnuPG/MacGPG2) 2.2.40; Copyright (C) 2022 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.

私钥可用。

sec  rsa4096/0000000000000000
     创建于:2022-11-20  有效至:永不       可用于:SC  
     信任度:绝对        有效性:绝对
ssb  rsa4096/0000000000000000
     创建于:2022-11-20  有效至:永不       可用于:E   
ssb  rsa2048/1111111111111111
     创建于:2022-11-20  有效至:永不       可用于:S   
     卡号: 0000 00000000
ssb  rsa2048/2222222222222222
     创建于:2022-11-20  有效至:永不       可用于:E   
     卡号: 0000 00000000
ssb  rsa2048/3333333333333333
     创建于:2022-11-20  有效至:永不       可用于:A   
     卡号: 0000 00000000
[ 绝对 ] (1). Test <test@gmail.com>

注意看哈,刚才将证书导入到 YubiKey 之后,导入的证书下面都多了个「卡号」。

然后我们可以试试拿它来签名:

echo foo | gpg --clearsign

然后输入个密码就 OK 啦。也可以试试把 YubiKey 拔掉,再来试试,应该就失败了。——嗯,这就是我们想要的~

我忘密码啦

  • PIN 码输错三次,会被锁定,需要输入 Reset Code 来解锁
  • Reset Code 输错三次,会被锁死,只能物理重置
  • Admin PIN 设置的时候如果短于 8 位,会被立即锁死,只能物理重置
  • Admin PIN 输错三次,会被锁死,只能物理重置

物理重置的方法比较简单……但重置了之后就啥都没了哈~

首先将下面这些东西随便存成个文件(比如 foo.txt

/hex
scd serialno
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 e6 00 00
scd apdu 00 44 00 00
/echo Card has been successfully reset.

然后输入

gpg-connect-agent -r foo.txt

做绝一点,不留后路

嗯,我们可以本地删除所有 key……

先删除私钥:

gpg --delete-secret-keys XXXXXXXX

再用删除公钥

gpg --delete-keys XXXXXXXX

然后插上 YubiKey,使用下面的命令看看内容

gpg --card-status

里面能看到你的主密钥和三个子密钥,但是只有摘要没有其他内容。

gpg --card-edit
fetch
list

你会发现,这时候密钥 “又回来了”,但是在主密钥后面多了个 #。系统会建立一个像是指针的东西,指向智能卡。

然后可以使用 gpg –card-status 看看信息。

配置 SSH 免密码访问

看你想怎么用了。有两个用法:

  • 导出 SSH 公钥私钥,然后一切按 SSH 的东西来
  • 导出 SSH 私钥,然后把 SSH 鉴权的事情交给 gpg-agent

生成 SSH Public Key

去上面翻翻,有一个 Key 的用途是 Auth。把它的 ID 记下来

gpg --export-ssh-key THE_AUTH_KEY > id_rsa.pub

然后就可以把这个公钥文件上传到服务器上了

ssh-copy-id -f -i id_rsa.pub user@192.168.100.100

或者,可以直接将文件内容 copy 到服务器的 ~/.ssh/authorized_keys 文件里面。

配置 Shell

这里主要是配置 gpg-agent 这个东西。蛮玄学的。我一直不怎么能配置成功。

首先,在.zshrc 里面找到 plugin ,参照注释里的写法,加入 gpg-agent 插件。

然后输入 gpg-agent 确定一下 gpg-agent 这个东西有没有安装。没的话顺手装一个~

然后看一下 ~/.gnupg/gpg-agent.conf 文件,主要是看看里面有没有 enable-ssh-support 这句话,没有的话补上。还有人说要把这个文件改成这个样子

# For Macos, use this
pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac
# For linux, use this
#pinentry-program /usr/bin/pinentry

# enables SSH support (ssh-agent)
enable-ssh-support

use-standard-socket

# default cache timeout of 600 seconds
default-cache-ttl 600
max-cache-ttl 7200

反正这里就很玄学。我只成功过两次,成功率 30% 左右。或者照着其他教程试试?

生成 SSH Private Key

这个东西其实不是必须的。只是因为我一直用 gpg-agent 不成功,所以想,直接导出个 SSH Private Key 来代替……如果能用 gpg-agent 来做的话,还是别走这个歪门邪道哈,要不然上面做的那么一大堆东西不就白费了😂

首先安装 monkeysphere 这个东西。然后执行

gpg --export-secret-keys XXXXXXXX | openpgp2ssh XXXXXXXX > ~/.ssh/id_rsa

或者

gpg  --export-secret-subkeys  XXXXXXXX | openpgp2ssh XXXXXXXX > ~/.ssh/id_rsa

上面的命令,key 是你的主密钥;下面的命令,key 是你的用于 Auth 的密钥。

在 YubiKey 里面操作

YubiKey 里面内置了一个叫 PIV 的程序,可以在 YubiKey Manager 里面进行配置。很多概念和 GPG 很像,但又不完全相同:

  1. 密码:PIN 为 6 位,默认为 123456;PUK 为 6-8 位,默认为 12345678;AdminCode 为 48 位,默认为 010203040506070801020304050607080102030405060708 ,并且可以用 PIN 来保护。
  2. 证书分为「Auth、Sign、Key Manage、Card Auth」四个。好像和 GPG 的「Sign、Encrypt、Auth」不完全对应。好像内置了一个 Private Key,然后通过这个 Private 生成一些其他东西,并且是可以导出的。
  3. 对 PIV 做 Reset 并不会将 GPG Reset 掉,反之亦然。因为在 YubiKey 上,GPG 和 PIV 是两个不同的程序。

然后需要注意的是,PIV 不是 GPG,PIV 不是 GPG,PIV 不是 GPG。所以用 gpg-agent 来搞 PIV 是完全行不通的。

参考资料


Posted

in

by

Tags:

Comments

《“GPG 使用教程”》 有 2 条评论

  1. […] GPG 使用教程的坑。这个坑是 3 年前刨的,当时想把 GPG […]

  2. […] 可以看这篇重新整理过的文章。每一步操作做啥都写清楚了。 […]

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注