You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用GitPython验证Git已签名提交并识别对应GPG公钥指纹

GPG提交签名验证与指纹获取实现方案

最简方案:调用Git内置验证命令(推荐)

  • 优势:不需要手动解析提交内容、处理GPG逻辑,Git底层已经封装了完整的校验流程,准确率最高
  • 实现逻辑:直接用subprocess调用git verify-commit --raw <提交哈希>命令,该命令会自动调用本地GPG密钥环完成验证,解析输出即可拿到验证状态和对应的密钥指纹

完整代码示例:

from git import Repo
import subprocess

def get_commit_verify_result(repo_dir: str, commit_sha: str) -> tuple[bool, str|None]:
    # 调用git内置验证命令,--raw参数输出结构化结果
    cmd = [
        "git",
        "-C", repo_dir,
        "verify-commit",
        "--raw",
        commit_sha
    ]
    # git verify-commit的结构化输出默认打印到stderr
    res = subprocess.run(cmd, capture_output=True, text=True)
    is_valid = False
    gpg_fingerprint = None
    for line in res.stderr.splitlines():
        line_parts = line.strip().split()
        if len(line_parts) < 2:
            continue
        # GOODSIG标记代表签名合法有效
        if line_parts[1] == "GOODSIG":
            is_valid = True
        # VALIDSIG行第一个参数就是完整的GPG公钥指纹
        elif line_parts[1] == "VALIDSIG":
            gpg_fingerprint = line_parts[2]
    return is_valid, gpg_fingerprint

# 结合你原有的遍历代码
repo_dir = "/path/to/your/repo"
repo = Repo(repo_dir)
fifty_first_commits = list(repo.iter_commits('master', paths="dir/in/repo/", max_count=5000))
for c in fifty_first_commits:
    if not c.gpgsig:
        continue
    is_valid, fingerprint = get_commit_verify_result(repo_dir, c.hexsha)
    print(f"提交哈希: {c.hexsha}")
    print(f"签名是否有效: {is_valid}")
    print(f"签名密钥指纹: {fingerprint}")
    print("-"*50)

原生Python实现方案(使用python-gnupg库)

如果不想调用外部命令,可以用第三方python-gnupg库完成验证:

  • 先安装依赖:pip install python-gnupg
  • 需手动提取提交的原始待签名内容(剥离gpgsig字段后的提交对象数据),再交给GPG验证

代码示例:

import gnupg
from git import Repo

gpg = gnupg.GPG()
repo_dir = "/path/to/your/repo"
repo = Repo(repo_dir)

for c in repo.iter_commits('master', paths="dir/in/repo/", max_count=5000):
    if not c.gpgsig:
        continue
    # 提取提交的原始待签名数据
    commit_data = repo.git.cat_file("commit", c.hexsha)
    # 剥离签名部分,拿到原始待签名内容
    signed_data = ""
    in_signature = False
    for line in commit_data.splitlines(keepends=True):
        if line.startswith("gpgsig"):
            in_signature = True
        if in_signature:
            if not line.startswith(" "):
                in_signature = False
            else:
                continue
        signed_data += line
    # 验证签名
    verify_res = gpg.verify(signed_data + c.gpgsig)
    print(f"提交哈希: {c.hexsha}")
    print(f"签名是否有效: {verify_res.valid}")
    print(f"签名密钥指纹: {verify_res.fingerprint}")
    print("-"*50)

注意事项

  • 两种方案都依赖本地密钥环已经导入了对应提交的GPG公钥,未导入公钥的情况下签名会判定为无效,也无法获取到完整指纹
  • 调用Git命令的方案兼容性更强,不需要处理不同Git版本提交对象的格式差异,更推荐使用

内容的提问来源于stack exchange,提问作者Joe Jasinski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 05:27:03