本地手动验证Git commit GPG签名出现BAD signature如何解决
Git commit 本地签名验证失败原因及解决方法
核心问题根源
你得到签名校验失败的核心原因是:你准备的commit.txt和Git实际签名时使用的原始提交数据结构完全不一致。Git对commit做GPG签名时使用的原文,不是git log或普通git cat-file -p展示的格式化内容,有特定的结构要求。
具体错误点
- 你提取的
commit.txt包含了不必要的提交哈希展示行(开头的commit 0a68558e7e025afebf67b81bf48ecb8b0fa7c06d是展示内容,不属于原始提交对象的正文) - Git签名时会先把提交对象里的
gpgsig签名字段及对应所有缩进的签名内容完全移除,剩余内容才是参与签名的正文部分,你没有做这个过滤操作 - 原始被签名的内容还要额外加前缀:
commit <剩余正文的字节数>\0(\0是ASCII空字符),你缺失了这个前缀 - 额外注意:如果你的文件换行符用了Windows的CRLF格式,也会因为字节不匹配导致校验失败,需要统一用LF换行
正确操作步骤
- 提取移除签名段的提交正文:
git cat-file commit 0a68558e7e025afebf67b81bf48ecb8b0fa7c06d | sed '/^gpgsig /,/^[^ ]/d' > raw_commit.txt
- 计算上述文件的字节数,生成包含前缀的完整待校验原文:
printf "commit %s\0" $(wc -c < raw_commit.txt) | cat - raw_commit.txt > signed_payload.txt
- 提取正确格式的签名文件:
从git cat-file -p的输出里找到gpgsig字段对应的所有缩进行,去掉每行开头的空格,首尾保留PGP签名的头标记和尾标记,存储为doc.sig,确保换行格式为LF - 执行校验命令:
gpg --verify doc.sig signed_payload.txt
就能得到和git verify-commit一致的合法校验结果。
内容的提问来源于stack exchange,提问作者Robert Lemiesz
相关产品推荐
相关产品推荐

