XingPiaoLiang's

Back

GPG(GNU Privacy Guard)#

GPG(GNU Privacy Guard) 是一套基于 OpenPGP 标准(RFC 4880) 的加密与签名工具,广泛用于数据加密、身份认证与内容签名。它是自由软件,是 PGP(Pretty Good Privacy)的开源替代方案。

基本原理#

GPG 使用 非对称加密算法,即:每位用户拥有一对密钥:

  • 公钥(Public Key):可以公开分享,供他人使用。
  • 私钥(Private Key):必须妥善保管,仅用户本人持有kkk

根据上面的机制,,我们可以实现两大重要功能

  • 加密: 发送者用你的公钥加密 → 只有你能用私钥解密
  • 数字签名: 你使用私钥签名,别人通过公钥就可以验证这是你签发的内容

常见的用途:

  • Git 提交签名(验证代码作者身份)
  • 软件发行签名(验证发布包完整性与合法性)
  • 加密通信(通过邮件或文件传输加密数据)
  • 身份认证(作为安全凭证的一部分)

简单来说,GPG 为我们提供了一个非常炫酷的「数字签名」方式。

Github 中使用 GPG#

在参与开源项目的时候,都会要求贡献者使用 GPG 签发自己的 commit,以认证自己的代码提交记录,使用 GPG 签名的 commit 在 Github 中会有炫酷的 verified 字样:

展开就会看见详细的签名信息:

生成新的 GPG 密钥对#

首先我们要下载生成密钥对所需要的 GPG 命令行工具,或者是下载对应操作系统的 GUI 客户端(windows).

这里我们使用 Linux 命令行工具 gpg 最简单的安装方法(直接通过包管理器安装),当然了我们能使用最新版本的最好,一般通过包管理器拉下来的版本都比较落后。

这里的机器是 Ubuntu-22.04:

sudo apt install gpg
bash

安装完毕之后,使用以下命令开始生成新的 GPG 密钥对 (version > 2.1.17):

gpg -full-generate-key
bash

接下来的步骤包含许多需要我们选择的配置,(签名算法等等):

$ gpg --full-generate-key
gpg (GnuPG) 2.4.7-unknown; Copyright (C) 2024 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)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (14) Existing key from card
Your selection?
Please select which elliptic curve you want:
   (1) Curve 25519 *default*
   (4) NIST P-384
   (6) Brainpool P-256
Your selection? 
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

GnuPG needs to construct a user ID to identify your key.

Real name: erasernoob
Email address: erasernoobx@outlook.com
Comment: 
You selected this USER-ID:
    "erasernoob <erasernoobx@outlook.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.
bash

上述流程包含以下几个步骤:

  • 选择我们需要哪种具体的 key Enter 选择默认 ECC
  • 选择 key 的大小 Enter 选择默认
  • 选择密钥的过期时间 0 为永不过期
  • 确定配置是否完成
  • 配置你的个人信息
    • 用户名(随便填)
    • 邮箱(如果要使用 Github 那么就一定要填写在 Github 上已经验证的邮箱,这样 Github 才能验证你的身份,以及 commit 收集)
  • 配置完成,最终会通过 GUI 窗口的形式弹出对话框填写你的 Passphrase 非常重要,每次使用都需要填写

填写完毕之后,公钥和密钥就生成完毕了:

gpg: /c/Users/admin/.gnupg/trustdb.gpg: trustdb created
gpg: directory '/c/Users/admin/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/c/Users/admin/.gnupg/openpgp-revocs.d/342A3A02ADE7ED544D25A8E5828136735CCFD941.rev'
public and secret key created and signed.

pub   ed25519 2025-06-13 [SC]
      342A3A02ADE7ED544D25A8E5828136735CCFD941
uid                      erasernoob <erasernoobx@outlook.com>
sub   cv25519 2025-06-13 [E]
bash

以上就会自动生成 GPG 密钥信息,有以下部分组成:

  • pub 主公钥
  • ed25519 主密钥算法
  • 2025-06-13 创建日期
  • SC 此密钥用途:Signing(签名),Certification(认证)
  • 342A...FD941 密钥指纹(fingerprint)(40 位)
  • uid 用户ID
  • sub 子密钥,cv25519 用于加密([E])

以上密钥指纹中,我们需要的是 Key ID 也就是指纹的最后16位,我们可以使用以下的命令让 gpg 以长 id 的形式打出:

gpg --list-secret-keys --keyid-format=long
bash

命令结果会以长 ID 形式打印出所有当前的 GPG 密钥对信息:

$ gpg --list-secret-keys --keyid-format=long
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
[keyboxd]
---------
sec   ed25519/828136735CCFD941 2025-06-13 [SC]
      342A3A02ADE7ED544D25A8E5828136735CCFD941
uid                 [ultimate] erasernoob <erasernoobx@outlook.com>
ssb   cv25519/8FC6A81A9304953C 2025-06-13 [E]
bash

也就是说我们需要的 Key ID 就是 828136735CCFD941

导出公钥#

gpg --armor --export 828136735CCFD941
# Prints the GPG key ID, in ASCII armor format
bash

使用上面获得的 Key ID,我们就可以需要交给对方的公钥:

-----BEGIN PGP PUBLIC KEY BLOCK-----
......
CAsCBBYCAwECHgcCF4AACgkQgoE2c1zP2UEzJAEA54H9E64Neti+D2lGwI1kpmGU
LtuM663assOrBDT7zskA/jQVb7dGff5QF+lFr9SMmVEzZaccoDfU/x3lvnoR/CQG
uDgEaEw01hIKKwYBBAGXVQEFAQEHQKjkXsddomXdvucO8wlm/f7HQirWEco2KBW8
yusqMsVqAwEIB4h4BBgWCgAgFiEENCo6Aq3n7VRNJajlgoE2c1zP2UEFAmhMNNYC
GwwACgkQgoE2c1zP2UECUwEAy3y4GrPxcI1icxErmnIlvow/afPucmuFCFTuh6r2
efgA/jsWXHso2n0Bi6YvEgx3APwNRcdZk9DaAl6Z5A0hrGQC
=65Yz
-----END PGP PUBLIC KEY BLOCK-----
bash

配置 Git GPG 签名#

获得上述的公钥以后,我们需要将其上传到 Github 中。

你需要用 key ID

git config --global user.signingkey  828136735CCFD941
bash

如果你希望 Git 自动使用 GPG 签名提交:

git config --global commit.gpgsign true
git config --global gpg.format gpg
# 始终添加 Signed-off-by
git config --global format.signoff true
bash

签名命令示例#

git commit -S -m "Add new feature"
git tag -s v1.0.0 -m "Release v1.0.0"
bash

这下你的数字签名就制作完成了.

迁移设备密钥对#

当拥有了多台设备进行主力开发,或者是需要切换到多个环境,比如 devcontainer 等等。但是再次配置一个新的 GPG 密钥又显得相对比较繁琐,所以我认为后续直接迁移已有的密钥对更加方便。

  1. 首先,在原设备导出 GPG 私钥

    # 查找对应的密钥 ID
    gpg --list-secret-keys --keyid-format LONG
    bash

    会出现类似下面的输出:

    sec   rsa4096/ABCDEF1234567890 2024-01-01 [SC]
          ...
    uid           [ultimate] Your Name <you@example.com>
    bash

    后面那串长哈希值,就是对应的 KEY ID

    接着导出私钥:

    gpg --export-secret-keys ABCDEF1234567890 > private.key
    # 导出公钥 (optional)
    gpg --export ABCDEF1234567890 > public.key
    bash
  2. 在新设备中导入私钥

    gpg --import private.key # import private
    gpg --import public.key # optional
    bash
  3. 导入私钥以后需要在本地配置该密钥对的相关信息,在本地选择信任该密钥

    gpg --edit-key ABCDEF1234567890 
    bash

    接下来将进入交互模式:

    trust
    bash

    输入 trust 代表对该密钥信任,同时会让你选择信任程度,根据提示选择信任等级,一般选择 5 = I trust ultimately,然后输入 quit 退出。

  4. 这样就导入成功了,可以使用以下命令来测试,密钥是否导入成功

    echo "test" | gpg --clearsign
    bash

输入密码问题#

在上面的测试过程中,你可能会遇到一个奇怪的不能理解的报错问题:

erasernoob@eraser:~/$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
test
gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device
bash

这一一般都是由于 pinentry 可视化界面未安装好或配置错误导致不能弹出弹窗并输入密码。可以选择安装但是没有很大的必要,通过以下步骤可以选择在终端中输入自己的密码:

  • 设置 GPG_TTY
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc
source ~/.bashrc
bash

再次测试,发现就可以在终端中输入密码了。

在 Github 使用 GPG 签名指南
https://astro-pure.js.org/blog/gpg
Author erasernoob
Published at June 13, 2025
Comment seems to stuck. Try to refresh?✨