Skip to content

简单入门GPG公钥,从此再也不担心被仿冒

Posted on:2023年3月15日 at 11:40

GPG是什么?

GPG是GNU Privacy Guard的缩写,是自由软件基金会的GNU计划的一部分。它基于非对称加密算法,用于认证你的身份,不被他人仿冒,它和git有很高的集成度。

我该如何使用GPG?

生成一个GPG私钥

(以下带有尖括号的是自己写的注释,命令里实际上没有)

$ gpg --full-generate-key
gpg (GnuPG) 2.2.29-unknown; Copyright (C) 2021 Free Software Foundation, Inc.
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 (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 1<对于最初开始使用的人建议这>
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
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: Rickyxrc<输入你的名>
Email address: rickyxrc@outlook.com<输入你的电子邮>
Comment:<可以写注释方便区分>
You selected this USER-ID:
    "Rickyxrc <rickyxrc@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.
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.
gpg: /c/Users/Ricky/.gnupg/trustdb.gpg: trustdb created
gpg: key 8D7A355BD4885E23 marked as ultimately trusted
gpg: directory '******<一个路径>' created
gpg: revocation certificate stored as '******<一个路径>'
public and secret key created and signed.

pub   rsa4096 2023-03-15 [SC]
      080428007B076747654F36CA8D7A355BD4885E23<这是你的key id>
uid                      Rickyxrc <rickyxrc@outlook.com>
sub   rsa4096 2023-03-15 [E]

建议再生成一张撤销证书,如果以后私钥泄露或其他原因,可以请求外部的公钥服务器撤销你的公钥。

$ gpg --gen-revoke 080428007B076747654F36CA8D7A355BD4885E23 > revoke_cert

sec  rsa4096/8D7A355BD4885E23 2023-03-15 Rickyxrc <rickyxrc@outlook.com>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 0
Enter an optional description; end it with an empty line:
>
Reason for revocation: No reason specified
(No description given)
Is this okay? (y/N)y

ASCII armored output forced.
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!

上传GPG公钥(只能上传公钥)

$ gpg --send-keys rickyxrc@outlook.com
gpg: sending key 8D7A355BD4885E23 to hkps://keyserver.ubuntu.com

这个公钥上传到哪里无所谓,最后所有GPG密钥服务器都会通过密钥交换收到你的密钥。

但是,因为这一步没有身份认证,其他人可以冒充你上传公钥,所以我们需要额外的方式告诉别人这个上传的GPG公钥是真实可信的。

$ gpg --fingerprint
/c/Users/<你的用户名>/.gnupg/pubring.kbx
---------------------------------
pub   rsa4096 2023-03-15 [SC]
      0804 2800 7B07 6747 654F  36CA 8D7A 355B D488 5E23
uid           [ultimate] Rickyxrc <rickyxrc@outlook.com>
sub   rsa4096 2023-03-15 [E]

这其中 0804 2800 7B07 6747 654F 36CA 8D7A 355B D488 5E23 就是你的密钥指纹,你可以将它上传到你的github主页或者其他地方来,比如这是我的github主页

如果你想要在github上显示verified标志,那么还需要将gpg公钥上传到github。

查询其他用户的密钥

$ gpg --search-keys Rickyxrc
gpg: data source: https://162.213.33.9:443
(1)     Rickyxrc <rickyxrc@outlook.com>
          4096 bit RSA key 8D7A355BD4885E23, created: 2023-03-15
Keys 1-1 of 1 for "Rickyxrc".  Enter number(s), N)ext, or Q)uit > numbers

可以指定 --keyserver 来使用你指定的公钥服务器查询。

导出GPG公钥

$ gpg --armor --export Rickyxrc

执行后会输出你本地对应Keyid的公钥。

导出GPG私钥[敏感操作]

$ gpg --armor --export-secret-keys Rickyxrc
<你的私钥文件输出>

加密和解密

使用私钥加密文件

这里加密的定义是:使用自己的私钥在不公开私钥的情况下根据原文件的信息生成一个新文件,所有人都可以获得这个文件,但是只有持有对应私钥的人才能解密(获取文件内容)。

$ gpg --recipient 接收者的公钥ID --output 加密后的文件 --encrypt 加密前的文件
$ gpg --search-keys Rickyxrc
gpg: data source: https://162.213.33.9:443
(1)     Rickyxrc <rickyxrc@outlook.com>
          4096 bit RSA key 8D7A355BD4885E23<这里就是接收者的公钥ID>, created: 2023-03-15
Keys 1-1 of 1 for "Rickyxrc".  Enter number(s), N)ext, or Q)uit > numbers

解密由私钥加密的文件

$ gpg --decrypt 加密后的文件 --output 加密前的文件
 $ gpg 加密后的文件
gpg: encrypted with 4096-bit RSA key, ID 3E4C0A26B696C84D<发送者的公钥id>, created 2023-03-15
      "Rickyxrc <rickyxrc@outlook.com>"
<文件信息>

签名和验签

签名的定义是:使用自己的私钥在不公开私钥的情况下根据原文件的信息生成一个新文件,所有持有私钥对应公钥的人都可以检验这个文件的发出者是否为私钥持有者本人。

签名

$ gpg --armor<是否使用ASCII形式的签名文件,不加就是二进制> --detach-sign 签名前的文件 <生成单独的签名文件,与源文件分>

验证签名

$ gpg --verify <签名文> <源文>
gpg: Signature made Wed Mar 15 11:13:31 2023
gpg:                using RSA key 080428007B076747654F36CA8D7A355BD4885E23
gpg: Good signature from "Rickyxrc <rickyxrc@outlook.com>" [ultimate]

同时签名和加密

$ gpg --local-user <发信者keyid> --recipient <接收者keyid> --armor --sign --encrypt demo.txt

git和gpg一起使用

打开git的gpg功能

$ git config --global user.signingkey <keyid>
$ git config --global commit.gpgsign true

为以前的所有提交增加签名

$ git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD

检查git仓库签名

git log --show-signature

在提交时签名

git commit -m "提交信息" -S


在 Rickyxrc's blog 出现的文章,若无特殊注明,均采用 CC BY-NC-SA 4.0 协议共享,也就是转载时需要注明本文章的地址,并且引用本文章的文章也要使用相同的方式共享。