[洛谷日报#296]GPG 入门指南

StudyingFather

2020-05-01 11:36:36

Personal

GnuPG(GPG)是由 GNU 在 [PGP](https://en.wikipedia.org/wiki/Pretty_Good_Privacy) 基础上开发的加密软件。 通过 GPG,您可以为您的文件进行签名,加密等操作。 ## 1 安装 GPG 对于 Linux 用户,可以通过包管理器进行安装。 对于 Windows 用户,可以下载 [gpg4win](http://www.gpg4win.org/)。gpg4win 提供图形化界面,不过笔者还是推荐在命令行下进行操作。 ## 2 生成密钥 在终端下输入 `gpg --generate-key` 来生成一对新的密钥。 这时候 gpg 会询问您采用何种加密方式,默认情况下采用 RSA 进行加密和签名。 ``` 请选择您要使用的密钥类型: (1) RSA 和 RSA (默认) (2) DSA 和 Elgamal (3) DSA(仅用于签名) (4) RSA(仅用于签名) 您的选择是? ``` (关于各加密方式的实现和安全性,可以自行查阅资料,这里不再赘述) 接下来 gpg 会询问生成密钥的长度。对于 RSA,默认情况下是 3072 位。为了安全起见,推荐将密钥长度设置为 4096 位。 在完成密钥长度的设置后,gpg 会询问密钥的过期时间。 ``` 请设定这个密钥的有效期限。 0 = 密钥永不过期 <n> = 密钥在 n 天后过期 <n>w = 密钥在 n 周后过期 <n>m = 密钥在 n 月后过期 <n>y = 密钥在 n 年后过期 密钥的有效期限是?(0) ``` 默认情况下密钥永远不会过期,如果你的密钥需要长期使用,且能保证自己能安全保管私钥,推荐设置为永不过期。 在完成上述设置后,gpg 会让你输入自己的姓名,邮箱等信息,这些信息将会用于签名。 最后一步是设置密码来确保私钥的安全。 在生成密钥的时间里,按照 gpg 的要求,随便敲敲你的键盘,让随机数生成器攒够熵吧! 然后你就生成了一对密钥。 **切记:保管好你的私钥!** **切记:保管好你的私钥!** **切记:保管好你的私钥!** ## 3 导出密钥 首先使用 `gpg --list-keys` 可以列出系统中已有的密钥。 列表中那一大串 hash 值是密钥的指纹(你也可以通过 `gpg --fingerprint [uid]` 的方式来查看密钥指纹)。 接下来我们将公钥导出,这样别人就可以用公钥加密文件,向我们发送了。 ``` gpg --armor --output public-key.txt --export [uid] ``` uid 可以是如下参数(只要能唯一确定密钥就行):你的姓名,密钥指纹的后若干位。`--armor` 意味着导出 ASCII 文件。 你可以将这个公钥直接贴在网站上,让别人用这个公钥加密,但这样真的安全吗? 假如网站不安全,攻击者可能会把你的公钥换掉,换上攻击者的公钥,这样攻击者就可以拦截别人给你发的文件了。 一种简单的解决方案是把密钥上传到专门存储的服务器。 像这样: ``` gpg --send-keys [uid] --keyserver pool.sks-keyservers.net ``` 现在你只需告诉别人你的公钥指纹就行。别人利用这个公钥指纹就可以获取你的公钥,方法下面会讲到。 ## 4 导入密钥 在得到公钥文件的前提下,通过 `gpg --import [密钥文件]` 的方式可以进行导入。 你也可以通过密钥服务器导入: ``` gpg --keyserver pool.sks-keyservers.net --search-keys [uid] ``` ## 5 文件签名 现在我们准备公开发布一个文件,为了确保这个文件不被篡改,我们需要给这个文件签名,以确保这个文件确实是本人发布的。 ``` gpg --armor --detach-sign example.txt ``` 这个命令会生成一个 ASCII 签名文件 `example.txt.asc`。 现在我们将这个文件下载了下来,如果校验文件的真实性呢? ``` gpg --verify example.txt.asc example.txt ``` ## 6 文件加密 ``` gpg --recipient [uid] --output example.en.txt --encrypt example.txt ``` 这个命令将通过 uid 的公钥进行加密,加密后的文件为 `example.en.txt`。 对方收到文件后,用私钥进行解密: ``` gpg --decrypt example.en.txt --output example.txt ``` ## 7 在 Github 上为你的提交签名 如果你在 Github 网页版上为某个仓库作出了提交,会看见这个提交带有一个“已验证”标识。 ![](https://cdn.luogu.com.cn/upload/image_hosting/ub4jh7gf.png) 为提交签名表示提交是由本人作出的,防止其他人假借你的身份对仓库作出更改。 如果更改是在本地进行的,如何进行签名呢? 只需对 Git 进行如下配置: ``` git config --global user.signingkey [uid] ``` 然后在 commit 的时候加一个 `-S` 参数,就可以对你的提交签名了(注意 commit 时使用的邮箱应该和密钥的邮箱相同)。 (如果你想要每次提交都默认签名的话,执行 `git config --global commit.gpgsign true` 命令即可) commit 的时候系统会提醒你输入当初添加私钥时配置的密码,以确认身份。 这样本地的提交就带有签名了。下一步是将本地提交推送到 Github,首先我们需要将密钥添加到 Github 账户。 在设置页面点击 SSH and GPG keys,接下来点击 New GPG key 按钮添加新密钥。你需要提交你的**公钥**。 到这里就差不多了。如果你 commit 时使用的邮箱绑定了 Github 账户,你就可以看见你的本地提交已经被验证。 ![](https://cdn.luogu.com.cn/upload/image_hosting/54x74yaa.png) ## 8 补充说明 GPG 还可以为邮件加密,详情可以看邮件客户端的帮助。 在命令行下输入 `gpg --help` 可以获取 GPG 的帮助信息。 ## Reference - [GPG入门教程 - 阮一峰的网络日志](https://ruanyifeng.com/blog/2013/07/gpg.html) - [管理提交签名验证 - Github 帮助](https://help.github.com/cn/github/authenticating-to-github/managing-commit-signature-verification)