很多人在博客中都会贴上自己的 GPG 公钥,虽然我自己平时没有这种高加密的需求,但还是对这类技术产生了好奇,便打算自己给自己发一份邮件,然后自己解密

GPG 加密的原理

GPG 基于非对称加密:

  • 每个人有一对密钥:公钥(公开给别人)和私钥(自己保管)
  • 你使用对方的公钥加密邮件,只有对方的私钥才能解密

安装 GPG

我使用的是 mac,直接使用 brew 进行安装,Windows 下需要安装 gpg4win,我没用过就不多说了

brew install gpg

之后生成密钥:

gpg --full-generate-key

一般来说,会选择使用默认的 ECC 椭圆曲线密码学(Elliptic Curve Cryptography),至于 RSA 和 RSA 则兼容性较强,在一些比较老的设备上可以使用,但现在很少有不兼容 ECC 的了

还是使用默认的,因为性能较好,而且在 TLS、SSH 中也被广泛使用

后面需要输入你自己的名字和邮件

之后就按照它的提示来,需要多滑动一下鼠标和键盘,收集更多的随机熵

GPG 密钥是可以设置有效期的,可以根据自己的需求来,我自己设置的是一年,一年后就会过期,需要重新签署

查看密钥

在终端中输入:

gpg --list-keys

之后可以看到类似的:

pub   rsa4096 2025-04-22 [SC]
      ABCD1234EFGH5678IJKL9012MNOP3456QRST7890
uid           [ultimate] Me <me@example.com>

这个表的意思为:

pub      → 公钥(Public key)
rsa4096  → 使用的算法及长度
[SC]     → 签名 + 认证
uid      → 用户身份(Name + Email)
fingerprint → 唯一识别这个密钥的标志(ABCD1234EFGH5678IJKL9012MNOP3456QRST7890)

导出公钥

我们只有导出自己的公钥,将其发给别人,别人才能用我们的公钥对信息进行加密,之后发送给我们,再进行解密

在整个证书链中,我们需要先导出我们自己的公钥:

gpg --export --armor liusomes@gmail.com > liueic.asc

此时就会导出为 liueic.asc 这个公钥

这里的 liusomes@gmail.com 就是你想导出的那把公钥所对应的 UID(用户标识)

GPG 会根据这个字符串在密钥环里查找匹配的密钥:

  • 它可以是邮箱(如 me@example.com
  • 可以是名字(如 Alice)
  • 也可以是密钥指纹的一部分(如 1234 ABCD)

GPG 寻找是支持模糊查询,比如我也可以使用 liusomes 之类的进行导出,只要能匹配到就能导出,匹配不到则不导出

比较保险的方法是使用指纹进行导出,指纹就是上面我说的那个,你仍然可以使用相关的指令来查看:

gpg --list-keys

我们可以查看一下公钥的样子:

-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEaAiSHxYJKwYBBAHaRw8BAQdAw9qYSf/0/xtF3YinJwtUuPDhjfl+u1vRwcB2
qEEHZuq0G2xpdWVpYyA8bGl1c29tZXNAZ21haWwuY29tPoiZBBMWCgBBFiEEWDuK
reI9BI2mGxiuq8ScjkmqiHUFAmgIkh8CGwMFCQHhM4AFCwkIBwICIgIGFQoJCAsC
BBYCAwECHgcCF4AACgkQq8ScjkmqiHUjIwD/R4Z9nlJk83NQaXDdHUKLdzQXwbqN
E3AKeQnLhaRNtPkBAMpwpaINDasreGk5o1Eab6/hihejHZXXvObgcOboovUJuDgE
aAiSHxIKKwYBBAGXVQEFAQEHQJrEnSzaybW2Sn6OwOAopgViXMys9Y9wGE8AzMaI
32M3AwEIB4h9BBgWCgAmFiEEWDuKreI9BI2mGxiuq8ScjkmqiHUFAmgIkh8CGwwF
CQHhM4AACgkQq8ScjkmqiHWtKwEAvboWd7eVPfExQ1FR1xD4pCUbKvdM1t/V3EDe
CNok0QgA+IYSfhZ9VMYnkJVmZm5EOMtMhr/fBU2h0DqdlYGxyAQ=
=mdNt
-----END PGP PUBLIC KEY BLOCK-----

开头和结尾都有对应的标志,用一个 BLOCK 块给包裹起来了

导入朋友的公钥

假如你朋友给你发的是上文的字段,那么你应该把它在本地保存为 asc 文件,之后再进行导入

gpg --import friend.asc

之后通过查看朋友的公钥是否存在钥匙串中:

 gpg --list-keys
[keyboxd]
---------
pub   ed25519 2025-04-23 [SC] [有效至:2026-04-23]
      ABCD1234EFGH5678IJKL9012MNOP3456QRST7890
uid             [ 绝对 ] liueic <liusomes@gmail.com>
sub   cv25519 2025-04-23 [E] [有效至:2026-04-23]

pub   ed25519 2025-02-07 [SC] [有效至:2026-02-07]
      ABCD1234EFGH5678IJKL9012MNOP3456QRST7890
uid             [ 未知 ] aunssdsad <aunssdsad@gmail.com>
sub   cv25519 2025-02-07 [E] [有效至:2026-04-07]

加密发送

之后使用朋友的公钥来加密信件:

gpg --encrypt --recipient aunssdsad@gmail.com mail.txt
  • --encrypt :表示对文件进行加密
  • --recipient :指定接收者的邮件地址或对应的密钥 ID,这样系统就会使用对应的公钥进行加密执行后,GnuPG 会生成一个加密后的文件,通常文件名为 mail.txt.gpg

邮件正文本身无法直接通过命令行转为加密内容。如果需要在邮件正文中插入加密后的文本,可以使用 ASCII 裸文本的方式进行加密(clearsign/armor),例如:

gpg --encrypt --armor --recipient aunssdsad@gmail.com mail.txt

之后就可以使用邮件等方式进行发送给好友,最好附带自己的公钥,这样的话朋友在回信的时候也能使用加密

加密邮件

朋友拿到你的公钥之后,也可以使用你的公钥对他要发送给你的东西进行加密

我们拿到信息之后,可以先将其保存为 gpg 后缀的文件,之后再进行操作,不然会出现一些问题,比如:

这个错误是由于 GPG 无法在没有终端交互的情况下请求私钥的密码(passphrase),所以解密失败,最方便的解决方法就是保存为文件,然后使用命令进行解密:

gpg --decrypt file.gpg

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