为 Git Commit 添加 GPG 签名
status
Published
type
Post
slug
git-commit-with-gpg
date
Sep 19, 2023
tags
Git
Linux
Config
summary
本文介绍了如何使用 GPG 来为 Git Commit 添加签名。首先需要安装 GPG,并生成密钥对。然后将公钥导入到 GitHub 上,配置本机的 Git 使用该密钥对进行签名。配置完成后,每次提交 commit 时,都会使用相应的私钥进行签名,GitHub 会验证签名的有效性,并展示一个可信标识。
之前在 V2 以及其他论坛上都有有人发现异常的 commit 记录——明明是别人的提交却显示为了自己。导致此现象的原因是
git commit
时,相应的信息均来源于 git 配置好的邮箱/用户名,git 本身并没有对此进行校验,也即默认状态下,我们可以通过配置伪装为任意用户。要解决此问题,可以使用 GPG 来签名 commit 。GPG(GNU Privacy Guard)签名是一种通过非对称加密算法创建的数字签名,用于验证文件的来源和完整性。通过使用私钥对文件进行签名,接收者可以使用公钥来验证文件的签名是否有效。如果签名有效,则表明文件未被篡改且是来自预期的来源。
不同操作系统安装方法可以在GnuPG 官方下载页面 看到。
# 安装 (macOS 为例) brew install gpg # 验证 gpg --version
命令操作
# 终端命令行输入 gpg --full-generate-key # 根据提示依次选择密钥类型/长度/有效期等,回车选择默认 # 提示输入用户ID信息时,可根据实际情况填写 git 用户名和邮箱 # 生成完毕最后会显示生成的密钥ID # 列出已有的密钥对信息 # 正常 gpg --list-secret-keys # 长格式 gpg --list-secret-keys --keyid-format=long # 短格式 gpg --list-secret-keys --keyid-format=short # 以 ASCII 码形式显示公钥 gpg --armour --export <密钥ID> # 导出公钥为文件 gpg_pub_key.gpg gpg --output gpg_pub_key.gpg --armor --export <密钥ID> # 导出私钥为文件 gpg_sec_key.gpg gpg --output gpg_sec_key.gpg --armor --export-secret-key <密钥ID> # 导入公钥 gpg --import gpg_pub_key.gpg # 导入私钥 gpg --allow-secret-key-import --import gpg_sec_key.gpg # 备份 gpg -o gpg_key --export-options backup --export-secret-keys <ID> # 还原 gpg --import-options restore --import gpg_key gpg --edit-key <ID> trust
上传公钥至 GitHub
复制上面输出的以
-----BEGIN PGP PUBLIC KEY BLOCK-----
开头并以 -----END PGP PUBLIC KEY BLOCK-----
结尾的公钥信息。
打开 GitHub 设置中的 SSH and GPG keys ,点击 New GPG key
,将刚才复制的内容粘贴到 Key
中,Title
随意,完成添加。本机 Git 配置
# --global 为全局配置,需视具体情况而定 # 配置 git 使用的密钥对 git config --global user.signingkey <密钥ID> # 提交的时候加上 -S 参数即可对 commits 进行 GPG 签名 git commit -S -m "fix bug" # 强制启用 commit 密钥签名,配置后提交无需再添加 -S 参数 git config --global commit.gpgsign true # 可选,若之前配置过其他的密钥格式,可先取消该设置,从而使用默认的 openpgp 格式 git config --global --unset gpg.format # 强制启用 tag 密钥签名 git config --global tag.forcesignannotated true
完成上述配置后,在进行
git commit
操作时,git 便会使用相应的私钥来为 commit 内容签名。git push
后,GitHub 会使用上传的公钥来验证该签名后的commit,验证通过会展示一个可信标识。若命令执行失败,可通过
export GIT_TRACE=1
追踪更多细节进行排查。参考信息