撤销用于Git提交签名的PGP证书相关问题
应对PGP私钥泄露的完整方案:撤销旧密钥 + 历史提交重签指南
兄弟,我太懂你这种焦虑了——用PGP签了一年的提交,私钥泄露简直是晴天霹雳。我给你梳理一套完整的应对方案,分紧急止损和历史提交重签两部分来说,都是实战过的步骤:
第一步:先止损!撤销泄露的旧PGP密钥
这一步必须优先做,防止坏人用你的旧密钥伪造签名:
- 生成撤销证书:在你还能控制的设备上(比如没丢的备用电脑,或是密钥文件泄露但本地还有备份的情况),执行命令:
按照提示选择撤销原因(选"Key has been compromised"最准确),填写备注后,把生成的撤销证书保存成gpg --gen-revoke [你的旧密钥ID]revocation-cert.asc文件。 - 发布撤销证书:把这个撤销文件上传到PGP密钥服务器,让全网都知道这个密钥失效了:
也可以直接打开密钥服务器的网页,手动上传这个撤销文件。gpg --keyserver keys.openpgp.org --send-keys [旧密钥ID] - 通知协作团队:如果是多人维护的仓库,一定要立刻告诉所有人你的旧密钥已泄露,让他们执行
gpg --refresh-keys更新本地密钥库,避免误信任旧签名。
第二步:历史提交能不能重新签名?当然可以!
不过要提前说清楚:重签历史会完全重写仓库的提交历史,如果是公共仓库或者多人协作的仓库,必须和所有团队成员沟通到位,强制推送后大家需要重新同步,不然会有冲突。
具体流程如下:
- 生成新的PGP密钥:先创建一个全新的安全密钥,建议用硬件密钥(比如YubiKey)存储,或者至少把私钥加密备份:
按照提示选密钥类型(推荐RSA 4096)、有效期、个人信息,完成后记下新的密钥ID。gpg --full-generate-key - 配置Git使用新密钥:让Git默认用新密钥签名提交:
git config --global user.signingkey [新密钥ID] # 确保全局开启提交签名 git config --global commit.gpgSign true - 批量重签所有历史提交:用
git filter-repo工具(比旧的filter-branch更安全高效)来遍历每一个提交,重新签名。先确保你安装了filter-repo,然后在仓库根目录执行:
这个命令会逐个修改所有提交,用新密钥重新签名,过程可能有点久,取决于你提交的数量。git filter-repo --commit-callback ' import subprocess subprocess.run(["git", "commit", "--amend", "--no-edit", "-S"], check=True, cwd=repo.git_dir) ' - 强制推送到远程仓库:这一步会覆盖远程的历史,一定要确认团队都同意:
把git push --force-with-lease origin mainmain换成你的目标分支名,--force-with-lease比直接--force更安全,避免覆盖别人刚推送的提交。 - 团队同步指南:让团队成员执行以下命令同步新的历史:
注意:这会清除他们本地未推送的修改,所以要提醒大家先备份或推送自己的本地更改。git fetch origin git reset --hard origin/main
额外注意事项
- 如果是公共仓库,fork过这个仓库的用户需要手动同步你的新历史,这一点可以在仓库的README或者Issue里说明。
- 新密钥一定要做好备份:导出私钥并加密存储,比如:
把这个文件加密后存到安全的地方(比如加密U盘、密码管理器)。gpg --export-secret-keys [新密钥ID] > new-secret-key.asc - 可以在仓库的README里更新你的新密钥ID,让新贡献者能获取并信任你的新签名。
内容的提问来源于stack exchange,提问作者Nicolai Schmid
相关产品推荐
相关产品推荐

