在本地的 git 仓库中,我们需要设置用户名和邮箱地址才能提交新的更改。

git config --global user.name "Mona Lisa"
git config --global user.email "email@example.com"

值得注意的是,这并不需要跟你的 GitHub 账号的用户名或者邮箱地址一致。

这带来了一个很严重的问题:任何人都可以设置用户名和邮箱地址来伪装成你,由于 GitHub 会自动根据用户名和邮箱地址关联单次的提交为注册的 GitHub 的账户,所以别人可以仿冒你的身份进行提交更改。

幸运的是我们是可以解决这个问题的:GitHub 使用 GPG 协议来给某次提交进行签名,从而确保了身份的合法性。

GnuPG(The GNU Privacy Guard)是 OpenGPG 的一个免费的实现版本,通常简称 GPG。本文以 macOS 操作系统为例,简单介绍如何结合 GitHub 来使用 GPG。

安装 GPG

GPG 官方提供二进制文件可以安装为命令行的形式,也可以选择第三方的带有 GUI 界面的软件。

下载 GnuPG for OS X,安装完毕后就可以直接使用 gpg2 命令。之所以不是 gpg 是因为最新版本与 gpg 是不兼容的,你也可以两者同时安装使用。

$ gpg2
gpg: directory '/Users/jerry/.gnupg' created
gpg: keybox '/Users/jerry/.gnupg/pubring.kbx' created
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: Go ahead and type your message ...

在 macOS 下面,确保用户为当前用户。

$ ls -ld ~/.gnupg
drwx------  7 root  staff  224 Jan  5 20:58 /Users/jerry/.gnupg

如果不是当前用户,比如在早期的版本中 GPG 会默认安装为 root 账户,这显然是不对的(会导致 git 也必须使用 root 账户)。GPG 推荐使用当前用户的权限即可。

我们可以将 GPG 文件夹权限赋给当前用户:

sudo chown -R $(whoami) ~/.gnupg

在 Windows 下面,推荐安装 Gpg4win,最新版本下面可以直接使用 gpg 命令。

创建 key

$ gpg2 --full-generate-key
gpg (GnuPG) 2.2.17; Copyright (C) 2019 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)
Your selection?
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 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: Jerry Bian
Email address: JerryBian@outlook.com
Comment: macOS GPG for GitHub
You selected this USER-ID:
    "Jerry Bian (macOS GPG for GitHub) <JerryBian@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.

GitHub 推荐使用 4096 位的 RSA 协议的 key。通常我们不需要输入额外的密码(passphrase),否则每次 git commit 都需要手动输入。

查看生成的 key

$ gpg2 --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
/Users/jerry/.gnupg/pubring.kbx
-------------------------------
sec   rsa4096/AFF6BB3742XXXXXX 2019-10-16 [SC]
      78E1EDDF17D16894B5DC5FD0AFF6BB3742XXXXXX
uid                 [ultimate] Jerry Bian (macOS GPG for GitHub) <JerryBian@outlook.com>
ssb   rsa4096/9F3105AD87XXXXXX 2019-10-16 [E]

我们需要记下上面的 AFF6BB3742XXXXXX,这是我们的 GPG key ID。

添加到 GitHub

$ gpg2 --armor --export AFF6BB37423A515E
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBF2nI2gBEADD7uZagmWFMYWpbEhNNC
...
34aJFbDOqgJz37TpZMnW7fR37NLZ
=vA1l
-----END PGP PUBLIC KEY BLOCK-----

GitHub 端需要知道我们的公钥,复制上述结果到 Settings ->GPG Keys-> New GPG key

设置本地 Git

设置 git GPG 命令(macOS)。

$ git config --global gpg.program gpg2

在 Windows 下面,由于我们安装了 Gpg4win,gpg 命令默认会指向 Gpg4win 安装目录下面的 gpg.exe,以我的实践来看,接下来 commit 的时候会报错,类似于:

$ git commit -m "update README"
gpg: skipped "3D7155EAF21E7XXX": No secret key
gpg: signing failed: No secret key
error: gpg failed to sign the data
fatal: failed to write commit object

解决方案是:

git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"

设置 git GPG key。

$ git config --global user.signingkey 6446F78B91107XXX

强制每次提交都自动使用 GPG 签名。

$ git config --global commit.gpgsign true 

当我们提交新的 commit 的时候,git 就会帮我们自动使用 GPG 来签名。

如果使用 GitHub 网页进行提交 commit,GitHub 会自动帮我们签名。

(本文完)