LogoDevKit.best
Blog Post Image

Git 提交签名完整指南:GPG 与 SSH 签名详解

Git 提交签名完整指南:GPG 与 SSH 签名详解

在现代软件开发中,确保代码提交的真实性和完整性变得越来越重要。Git 提供了强大的数字签名功能,让开发者可以对自己的提交进行加密签名,确保代码来源的可信度。本文将详细介绍如何配置和使用 GPG 签名,以及新兴的 SSH 签名方式。

为什么需要提交签名?

提交签名能够:

  • 验证身份:证明提交确实来自声称的作者
  • 防止篡改:确保提交内容在传输过程中未被修改
  • 增强信任:在开源项目中建立代码贡献的可信度
  • 合规要求:满足某些企业或项目的安全规范

在 GitHub 上,已签名的提交会显示绿色的 "Verified" 标记,未签名或签名无效的提交则不会有此标记。

GPG 签名详解

GPG 基础概念

GPG (GNU Privacy Guard) 是一个完整的加密和数字签名解决方案,基于 OpenPGP 标准。它使用非对称加密算法,包含一对密钥:

  • 私钥:用于签名和解密,必须严格保密
  • 公钥:用于验证签名和加密,可以公开分享

安装 GPG

Linux (Ubuntu/Debian):

sudo apt update  
sudo apt install gnupg  

macOS:

brew install gnupg  

Windows:
下载并安装 Gpg4win

生成 GPG 密钥对

# 生成新的密钥对  
gpg --gen-key  

按提示依次输入:

  • 真实姓名
  • 邮箱地址(必须与 Git 配置的邮箱一致)
  • 密钥密码(强密码保护私钥)

管理 GPG 密钥

查看密钥

# 查看所有公钥  
gpg --list-keys
 
# 查看私钥(包含密钥 ID)  
gpg --list-secret-keys --keyid-format LONG  

导出公钥

# 导出 ASCII 格式的公钥  
gpg --armor --export 你的邮箱地址
 
# 导出到文件  
gpg --armor --export 你的邮箱地址 > public_key.asc  

备份和恢复

# 备份私钥(重要!)  
gpg --armor --export-secret-keys 你的邮箱地址 > private_key.asc
 
# 导入密钥  
gpg --import private_key.asc  

配置 Git 使用 GPG 签名

基本配置

# 设置用户信息(邮箱必须与 GPG 密钥匹配)  
git config --global user.name "Your Name"  
git config --global user.email "your_email@example.com"
 
# 获取密钥 ID(从 gpg --list-secret-keys 输出中获取)  
gpg --list-secret-keys --keyid-format LONG
 
# 配置签名密钥  
git config --global user.signingkey 你的密钥ID
 
# 启用自动签名  
git config --global commit.gpgsign true  
git config --global tag.gpgsign true  

环境配置

# 设置 GPG TTY(解决签名时的输入问题)  
export GPG_TTY=$(tty)
 
# 永久添加到 shell 配置  
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc  
# 或者对于 zsh 用户  
echo 'export GPG_TTY=$(tty)' >> ~/.zshrc  

macOS 特殊配置

# 安装 pinentry-mac(更好的密码输入体验)  
brew install pinentry-mac
 
# 配置 gpg-agent  
echo "pinentry-program /opt/homebrew/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
 
# 重启 gpg-agent  
gpg-connect-agent reloadagent /bye  

在 GitHub 上配置 GPG 公钥

  1. 导出你的 GPG 公钥:
gpg --armor --export 你的密钥ID  
  1. 复制输出的全部内容(包括 -----BEGIN PGP PUBLIC KEY BLOCK----------END PGP PUBLIC KEY BLOCK-----
  2. 在 GitHub 上添加:
  • 进入 Settings → SSH and GPG keys
  • 点击 "New GPG key"
  • 粘贴公钥内容
  • 点击 "Add GPG key"

使用 GPG 签名

自动签名

配置完成后,每次提交都会自动签名:

git add .  
git commit -m "Your commit message"  
# 会自动使用 GPG 签名  

手动控制签名

# 强制签名单次提交  
git commit -S -m "Signed commit"
 
# 禁用单次提交的签名  
git commit --no-gpg-sign -m "Unsigned commit"
 
# 签名标签  
git tag -s v1.0 -m "Signed tag"  

验证签名

本地验证

# 查看最近提交的签名信息  
git log --show-signature -1
 
# 查看多个提交的签名状态  
git log --pretty="format:%h %G? %an %s" -5  

签名状态标识:

  • G = 有效签名 (Good signature)
  • B = 无效签名 (Bad signature)
  • U = 签名有效但密钥不受信任 (Untrusted)
  • X = 签名已过期 (eXpired)
  • Y = 签名由过期密钥创建 (expired keY)
  • R = 签名由吊销密钥创建 (Revoked)
  • E = 签名验证错误 (Error)
  • N = 无签名 (No signature)

GitHub 验证

在 GitHub 上,正确配置的签名提交会显示:

  • Verified - 签名有效且公钥已添加
  • Unverified - 签名无效或公钥未添加
  • 无标记 - 提交未签名

SSH 签名:现代化的替代方案

从 Git 2.34 版本开始,Git 支持使用 SSH 密钥进行签名,这为已经熟悉 SSH 的开发者提供了更简单的选择。

SSH 签名的优势

  • 简化配置:复用现有的 SSH 密钥
  • 统一管理:一套密钥解决认证和签名
  • 减少复杂性:避免 GPG 的环境配置问题

配置 SSH 签名

生成 SSH 密钥(如果还没有)

# 生成 ed25519 密钥(推荐)  
ssh-keygen -t ed25519 -C "your_email@example.com"
 
# 或生成 RSA 密钥  
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"  

配置 Git 使用 SSH 签名

# 设置签名格式为 SSH  
git config --global gpg.format ssh
 
# 设置 SSH 签名密钥(使用公钥文件路径)  
git config --global user.signingkey ~/.ssh/id_ed25519.pub
 
# 启用自动签名  
git config --global commit.gpgsign true  

在 GitHub 上添加 SSH 签名密钥

  1. 复制你的 SSH 公钥:
cat ~/.ssh/id_ed25519.pub  
  1. 在 GitHub 上添加:
  • 进入 Settings → SSH and GPG keys
  • 点击 "New SSH key"
  • Key type 选择 "Signing Key"(注意不是 Authentication Key)
  • 粘贴公钥内容

SSH vs GPG 签名对比

特性SSH 签名GPG 签名
配置复杂度简单复杂
密钥管理复用现有 SSH 密钥需要专门的 GPG 密钥
生态支持较新,支持有限成熟,广泛支持
密钥格式SSH 公钥文件路径GPG 密钥 ID
适用场景个人项目,简化配置企业项目,严格安全要求

常见问题与解决方案

GPG 签名失败

问题:gpg: signing failed: Inappropriate ioctl for device

# 解决方案:设置 GPG TTY  
export GPG_TTY=$(tty)  

问题:gpg: signing failed: No secret key

# 检查密钥是否存在  
gpg --list-secret-keys
 
# 检查 Git 配置的密钥 ID 是否正确  
git config user.signingkey  

问题:密码输入界面无法显示(macOS)

# 安装并配置 pinentry-mac  
brew install pinentry-mac  
echo "pinentry-program /opt/homebrew/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf  
gpg-connect-agent reloadagent /bye  

签名验证问题

GitHub 上显示 "Unverified"

  1. 确认邮箱匹配:
git config user.email  
gpg --list-keys  
  1. 确认公钥已添加到 GitHub
  2. 确认密钥未过期

签名状态显示 "U" (Untrusted)

# 信任自己的密钥  
gpg --edit-key 你的密钥ID  
# 在交互界面中输入 trust,选择信任级别  

性能优化

缓存 GPG 密码

编辑 ~/.gnupg/gpg-agent.conf

default-cache-ttl 3600  
max-cache-ttl 86400  

禁用特定仓库的签名

# 在特定项目中禁用签名  
git config commit.gpgsign false  

最佳实践

密钥管理

  1. 定期备份私钥:将私钥导出并安全存储
  2. 设置密钥过期时间:建议 2-4 年,到期前续期
  3. 使用强密码:保护私钥的密码应该足够复杂
  4. 撤销泄露密钥:如果私钥泄露,立即撤销并生成新密钥

团队协作

  1. 统一签名策略:团队应该统一使用 GPG 或 SSH 签名
  2. 密钥服务器:考虑使用企业密钥服务器管理团队密钥
  3. CI/CD 集成:配置自动化流程验证提交签名

安全考虑

  1. 密钥轮换:定期更新签名密钥
  2. 多设备同步:安全地在多个设备间同步密钥
  3. 审计日志:记录密钥使用和签名活动

完整配置示例

GPG 签名完整配置

# 1. 安装 GPG  
brew install gnupg # macOS
 
# 2. 生成密钥  
gpg --gen-key
 
# 3. 获取密钥 ID  
KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep '^sec' | awk '{print $2}' | cut -d'/' -f2)
 
# 4. 配置 Git  
git config --global user.name "Your Name"  
git config --global user.email "your_email@example.com"  
git config --global user.signingkey $KEY_ID  
git config --global commit.gpgsign true
 
# 5. 设置环境  
echo 'export GPG_TTY=$(tty)' >> ~/.zshrc
 
# 6. 导出公钥  
gpg --armor --export $KEY_ID  

SSH 签名完整配置

# 1. 生成 SSH 密钥(如果没有)  
ssh-keygen -t ed25519 -C "your_email@example.com"
 
# 2. 配置 Git  
git config --global gpg.format ssh  
git config --global user.signingkey ~/.ssh/id_ed25519.pub  
git config --global commit.gpgsign true
 
# 3. 显示公钥用于添加到 GitHub  
cat ~/.ssh/id_ed25519.pub  

结论

Git 提交签名是现代软件开发中的重要安全实践。GPG 签名提供了成熟、全面的解决方案,适合对安全有严格要求的项目;而 SSH 签名则为个人开发者和小团队提供了更简化的选择。

选择哪种签名方式主要取决于:

  • 项目需求:企业项目通常偏好 GPG,个人项目可以选择 SSH
  • 团队规模:大团队建议统一使用 GPG,小团队可以考虑 SSH
  • 技术背景:熟悉 SSH 的团队可能更容易接受 SSH 签名

无论选择哪种方式,重要的是建立一致的签名策略,确保代码的完整性和可信

微信公众号二维码

🚀 关注我的公众号

与我一同探索独立开发与技术精进之路
获取最新的技术分享和开发心得

📱 扫码关注💡 技术分享🎯 独立开发

Publisher

zjy365Z
zjy365

2025/08/26

Categories

    Newsletter

    Join the Community

    Subscribe to our newsletter for the latest news and updates