GPG 簽名 Git Commit 完全指南 | 提升代碼安全性與身份驗證
在協作開發中,確保代碼提交的真實性和完整性至關重要。GPG(GNU Privacy Guard)簽名為 Git commit 提供了強大的身份驗證機制,防止他人偽造你的提交記錄。通過 GPG 簽名,GitHub、GitLab 等平臺會顯示綠色的 "Verified" 標識,證明該提交確實來自你。本文將詳細介紹從零開始的完整配置流程。
為什麼需要 GPG 簽名?
核心優勢
| 優勢 | 說明 |
|---|---|
| 🔒 身份驗證 | 證明提交確實來自你,防止身份偽造 |
| ✅ 完整性保護 | 確保提交內容未被篡改 |
| 🟢 可信標識 | GitHub/GitLab 顯示 "Verified" 徽章 |
| 🛡️ 安全防護 | 防止中間人攻擊和提交注入 |
| 📋 審計追蹤 | 提供不可抵賴的提交記錄 |
適用場景
- ✅ 開源項目貢獻:證明你的貢獻真實性
- ✅ 企業團隊協作:確保內部代碼來源可信
- ✅ 個人項目管理:提升代碼庫的專業度
- ✅ 合規要求:滿足某些行業的安全審計需求
GPG 安裝
brew install gpg
# or
brew cask install keybase不同平臺安裝方法
macOS
# 方法 1:Homebrew(推薦)
brew install gnupg
# 方法 2:MacGPG2(圖形界面)
# 下載:https://gpgtools.org/
# 驗證安裝
gpg --versionLinux
# Ubuntu/Debian
sudo apt-get install gnupg2
# CentOS/RHEL
sudo yum install gnupg2
# Arch Linux
sudo pacman -S gnupg
# 驗證安裝
gpg2 --versionWindows
# 方法 1:Gpg4win(推薦)
# 下載:https://gpg4win.org/
# 方法 2:Chocolatey
choco install gpg4win
# 方法 3:Scoop
scoop install gpg
# 驗證安裝
gpg --version常用命令
$ gpg --gen-key
$ gpg --list-keys
$ gpg --list-secret-keys
$ gpg2 --list-keys
$ gpg2 --list-secret-keys
$ gpg2 --keyserver hkp://pool.sks-keyservers.net --send-keys C6EED57A
$ gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys C6EED57A命令詳解
| 命令 | 功能 | 說明 |
|---|---|---|
gpg --gen-key | 生成新密鑰對 | 交互式嚮導 |
gpg --list-keys | 列出公鑰 | 查看所有公鑰 |
gpg --list-secret-keys | 列出私鑰 | 查看可用於簽名的密鑰 |
gpg2 --list-keys | 列出公鑰(v2) | GnuPG 2.x 版本 |
--send-keys | 上傳公鑰到服務器 | 分享公鑰 |
--recv-keys | 從服務器下載公鑰 | 獲取他人公鑰 |
生成 GPG key
gpg --gen-key具體步驟如下
$ gpg --gen-key
gpg (GnuPG) 2.2.15; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
注意:使用 "gpg --full-generate-key" 以獲得一個功能完整的密鑰產生對話框。
GnuPG 需要構建用戶標識以辨認您的密鑰。
真實姓名: Theo
電子郵件地址: fanxiaobin422@gmail.com
您選定了此用戶標識:
"Theo <fanxiaobin422@gmail.com>"
更改姓名(N)、註釋(C)、電子郵件地址(E)或確定(O)/退出(Q)? o
我們需要生成大量的隨機字節。在質數生成期間做些其他操作(敲打鍵盤
、移動鼠標、讀寫硬盤之類的)將會是一個不錯的主意;這會讓隨機數
發生器有更好的機會獲得足夠的熵。
gpg: 密鑰 8284896418BCC645 被標記為絕對信任
gpg: 目錄'/Users/xiexianbin/.gnupg/openpgp-revocs.d'已創建
gpg: 吊銷證書已被存儲為'/Users/xiexianbin/.gnupg/openpgp-revocs.d/11518af49eaa27d86ea01b5c901487ea218aeb1a.rev'
公鑰和私鑰已經生成並被簽名。
pub rsa2048 2019-05-16 [SC] [有效至:2021-05-15]
11518af49eaa27d86ea01b5c901487ea218aeb1a
uid xiexianbin <me@xiexianbin.cn>
sub rsa2048 2019-05-16 [E] [有效至:2021-05-15]詳細配置說明
步驟 1:選擇密鑰類型
# 使用完整生成模式(推薦)
gpg --full-generate-key
# 選項說明:
# (1) RSA and RSA (default) - 推薦
# (2) DSA and Elgamal
# (3) DSA (sign only)
# (4) RSA (sign only)
# (14) Existing key from card步驟 2:選擇密鑰長度
# 推薦配置:
RSA 密鑰長度應在 1024 位與 4096 位之間。
您想要用多大的密鑰尺寸?(2048) 4096
# 建議:
# - 個人使用:2048 位(足夠安全)
# - 企業/高安全:4096 位(更安全但稍慢)步驟 3:設置有效期
# 選項:
# 0 = 密鑰永不過期
# <n> = 密鑰在 n 天后過期
# <n>w = 密鑰在 n 周後過期
# <n>m = 密鑰在 n 月後過期
# <n>y = 密鑰在 n 年後過期
# 推薦:
# - 個人項目:0(永不過期)
# - 企業環境:1y 或 2y(定期輪換)步驟 4:填寫用戶信息
真實姓名: Your Name
電子郵件地址: your.email@example.com
註釋: GitHub Key(可選,用於區分多個密鑰)
# 重要提示:
# ⚠️ 郵箱必須與 Git 配置的郵箱一致!
# ⚠️ 確認信息無誤後再繼續步驟 5:設置密碼短語
# 輸入保護私鑰的密碼
# 建議使用強密碼(12+ 字符,包含大小寫、數字、符號)
# 可以使用密碼管理器保存
# 提示:
# - 密碼不會顯示在屏幕上
# - 需要輸入兩次確認
# - 忘記密碼將無法恢復私鑰!步驟 6:生成熵
# 系統需要收集隨機數據來生成密鑰
# 在此期間可以:
# - 敲擊鍵盤
# - 移動鼠標
# - 打開/關閉程序
# - 讀寫文件
# 等待直到顯示:
# "公鑰和私鑰已經生成並被簽名"查看 GPG key
gpg --list-keys
gpg --list-secret-keys示例
$ gpg --list-keys
/Users/xiexianbin/.gnupg/pubring.kbx
------------------------------------
pub rsa2048 2019-05-16 [SC] [有效至:2021-05-15]
11518af49eaa27d86ea01b5c901487ea218aeb1a
uid [ 絕對 ] xiexianbin <me@xiexianbin.cn>
sub rsa2048 2019-05-16 [E] [有效至:2021-05-15]輸出解讀
pub rsa2048 2019-05-16 [SC] [有效至:2021-05-15]
11518af49eaa27d86ea01b5c901487ea218aeb1a
uid [ 絕對 ] xiexianbin <me@xiexianbin.cn>
sub rsa2048 2019-05-16 [E] [有效至:2021-05-15]
# 字段說明:
# pub - 公鑰(Public Key)
# sub - 私鑰(Subkey,用於加密)
# rsa2048 - 算法和密鑰長度
# 2019-05-16 - 創建日期
# [SC] - 用途:S=簽名(Sign), C=認證(Certify)
# [E] - 用途:加密(Encrypt)
# 11518af4... - 密鑰指紋(Key ID)
# [ 絕對 ] - 信任級別密鑰
pub:公鑰sub:私鑰11518af49eaa27d86ea01b5c901487ea218aeb1a是 pub GPG key ID
導出公鑰
gpg --armor --export <pub GPG key ID>示例:
gpg --armor --export 11518af49eaa27d86ea01b5c901487ea218aeb1aGPG key 格式
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFz...(Base64 編碼的密鑰數據)
...
-----END PGP PUBLIC KEY BLOCK-----導出到文件:
# 導出到文件
gpg --armor --export your@email.com > gpg_public_key.asc
# 或直接複製終端輸出
gpg --armor --export your@email.com刪除GPG key
gpg --delete-keys <pub GPG key ID>
gpg --delete-secret-keys <pub GPG key ID>完整刪除流程:
# 1. 先刪除私鑰(必須)
gpg --delete-secret-keys 11518af49eaa27d86ea01b5c901487ea218aeb1a
# 2. 再刪除公鑰
gpg --delete-keys 11518af49eaa27d86ea01b5c901487ea218aeb1a
# 3. 驗證刪除
gpg --list-keys
gpg --list-secret-keys⚠️ 警告:刪除密鑰後無法恢復,請謹慎操作!
Github 配置 GPG
配置 GPG 公鑰到倉庫
Github Setting -> SSH and GPG keys -> New GPG Key 導入即可
詳細步驟
步驟 1:獲取公鑰
# 方法 1:導出到剪貼板(macOS)
gpg --armor --export your@email.com | pbcopy
# 方法 2:導出到文件
gpg --armor --export your@email.com > ~/gpg_key.asc
# 然後用文本編輯器打開復制
# 方法 3:直接查看
gpg --armor --export your@email.com
# 選中並複製全部內容(包括 BEGIN 和 END 行)步驟 2:添加到 GitHub
- 登錄 GitHub
- 點擊右上角頭像 →【Settings】
- 左側菜單選擇【SSH and GPG keys】
- 點擊【New GPG key】
- 粘貼公鑰內容
- 點擊【Add GPG key】
- 輸入 GitHub 密碼確認
步驟 3:驗證添加
- 公鑰會顯示在列表中
- 顯示創建日期和密鑰 ID
- 狀態為活躍
本地代碼倉庫啟用GPG Sign
通過 gpg --list-keys 查看 pub GPG key ID,後設置 git簽名 時用的 key
全局設置
# 配置已經生成的GPG Key ID
git config --global user.signingkey <pub GPG key ID>
# 配置啟用GPG簽名
git config --global commit.gpgsign true示例:
git config --global user.signingkey 11518af49eaa27d86ea01b5c901487ea218aeb1a
git config --global commit.gpgsign true指定倉庫設置,需要進入代碼目錄:
# 配置已經生成的GPG Key ID
git config --local user.signingkey <pub GPG key ID>
# 配置啟用GPG簽名
git config --local commit.gpgsign true驗證配置:
# 查看全局配置
git config --global --list | grep gpg
# 查看當前倉庫配置
git config --local --list | grep gpg
# 預期輸出:
# user.signingkey=11518af49eaa27d86ea01b5c901487ea218aeb1a
# commit.gpgsign=true配置說明:
| 配置項 | 作用 | 推薦 |
|---|---|---|
user.signingkey | 指定用於簽名的密鑰 ID | 必填 |
commit.gpgsign | 自動為所有 commit 簽名 | 推薦 true |
tag.gpgSign | 自動為 tag 簽名 | 可選 |
gpg.program | 指定 GPG 程序路徑 | 默認即可 |
重啟 gpg-agent
gpgconf –kill gpg-agent為什麼需要重啟?
- 清除緩存的密鑰信息
- 重新加載配置
- 解決簽名失敗問題
其他相關命令:
# 查看 gpg-agent 狀態
gpgconf --list-dirs
# 重啟特定組件
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
# 查看日誌
tail -f ~/.gnupg/S.gpg-agent上述示例
~ xiexianbin$ git config --global user.signingkey 11518af49eaa27d86ea01b5c901487ea218aeb1a
~ xiexianbin$ git config --global commit.gpgsign true
~ xiexianbin$ gpgconf –kill gpg-agent
gpg:OpenPGP:/usr/local/Cellar/gnupg/2.2.15/bin/gpg
gpg-agent:私鑰:/usr/local/Cellar/gnupg/2.2.15/bin/gpg-agent
scdaemon:智能卡:/usr/local/Cellar/gnupg/2.2.15/libexec/scdaemon
gpgsm:S/MIME:/usr/local/Cellar/gnupg/2.2.15/bin/gpgsm
dirmngr:網絡:/usr/local/Cellar/gnupg/2.2.15/bin/dirmngr
pinentry:密碼條目:/usr/local/opt/pinentry/bin/pinentry
~ xiexianbin$git 使用
提交
git commit -am "feature: something"
git push origin develop然後我們可以在 git 中看到 Verified 的標識。
如果不設置 git config --global commit.gpgsign true,提交的時候加上一個 -S 參數就可以為提交簽名:
git commit -S -m `your commit message`簽名提交流程
自動簽名(推薦):
# 已配置 commit.gpgsign=true
git add .
git commit -m "feat: add new feature"
# 自動彈出密碼輸入框
# 提交成功後顯示 Verified 標識手動簽名:
# 未配置自動簽名時
git commit -S -m "feat: add new feature"
# 指定密鑰
git commit -S<key-id> -m "feat: add new feature"批量提交簽名:
# 修改多個文件後
git add file1.js file2.js file3.js
git commit -S -m "refactor: update multiple files"提交 tag 時簽名
git tag -s ...詳細用法:
# 創建帶簽名的 tag
git tag -s v1.0.0 -m "Release version 1.0.0"
# 簽署已有的 tag
git tag -s v1.0.0 HEAD -f
# 驗證 tag 簽名
git tag -v v1.0.0
# 推送簽名 tag
git push origin v1.0.0查看日誌
git log --show-signature -1更多查看方式:
# 查看最近一次提交的簽名
git log --show-signature -1
# 查看所有提交的簽名狀態
git log --pretty=format:"%h %G? %aN %s"
# 僅顯示已驗證的提交
git log --pretty=format:"%h %G? %aN %s" | grep "^.* G .*"
# 圖形化查看
git log --graph --oneline --show-signature簽名狀態標識:
G - good signature(良好籤名)
B - bad signature(錯誤簽名)
U - good signature, unknown validity(未知有效性)
X - good signature, expired key(密鑰已過期)
R - good signature, revoked key(密鑰已撤銷)
E - cannot check (no public key)(無公鑰)
N - no signature(無簽名)高級配置
1. 配置 GPG Agent
編輯配置文件:
# macOS/Linux
nano ~/.gnupg/gpg-agent.conf
# 添加以下內容
default-cache-ttl 600
max-cache-ttl 7200
allow-preset-passphrase配置說明:
default-cache-ttl 600 # 密碼緩存時間(秒)
max-cache-ttl 7200 # 最大緩存時間(秒)
allow-preset-passphrase # 允許預設密碼(腳本自動化)重啟生效:
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent2. 配置 Pinentry
macOS 用戶:
# 使用 macOS 原生密碼輸入框
echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
# 安裝 pinentry-mac
brew install pinentry-macLinux 用戶:
# 使用 GTK 界面
echo "pinentry-program /usr/bin/pinentry-gtk-2" >> ~/.gnupg/gpg-agent.conf
# 或使用命令行
echo "pinentry-program /usr/bin/pinentry-curses" >> ~/.gnupg/gpg-agent.confWindows 用戶:
# Gpg4win 自帶 pinentry,通常無需配置3. 多密鑰管理
列出所有密鑰:
gpg --list-keys --keyid-format long切換默認密鑰:
# 查看當前配置
git config --global user.signingkey
# 修改為其他密鑰
git config --global user.signingkey NEW_KEY_ID為不同項目使用不同密鑰:
# 全局使用密鑰 A
git config --global user.signingkey KEY_A
# 特定項目使用密鑰 B
cd /path/to/project
git config --local user.signingkey KEY_B常見問題
$ GIT_TRACE=1 git commit -m "xxx"
22:03:55.417251 git.c:455 trace: built-in: git commit -m 'feature: jwt support'
22:03:55.424110 run-command.c:667 trace: run_command: gpg --status-fd=2 -bsau B5A1B728A2FD170FE0E6C4E2D6B71988603A67D2
error: gpg failed to sign the data
fatal: failed to write commit object
或
error: gpg 無法為數據簽名
fatal: 寫提交對象失敗解決辦法
echo export GPG_TTY=$(tty) >> ~/.bash_profile
export GPG_TTY=$(tty)重新執行,發現會彈出一個密碼輸入界面。
如果沒有解決,執行如下命令
$ gpg --status-fd=2 -bsau B5A1B728A2FD170FE0E6C4E2D6B71988603A67D2
# 如果卡住,執行
killall gpg-agent常見問題完整解決方案
問題 1:gpg failed to sign the data
症狀:
error: gpg failed to sign the data
fatal: failed to write commit object解決方案:
# 方案 1:設置 GPG_TTY(最常見)
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc # Linux
echo 'export GPG_TTY=$(tty)' >> ~/.zshrc # macOS
source ~/.zshrc
# 方案 2:重啟 gpg-agent
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
# 方案 3:檢查密鑰是否存在
gpg --list-secret-keys
# 方案 4:驗證 Git 配置
git config --global user.signingkey
git config --global commit.gpgsign
# 方案 5:測試手動簽名
echo "test" | gpg --clearsign問題 2:No secret key
症狀:
error: No secret key解決方案:
# 1. 檢查私鑰是否存在
gpg --list-secret-keys
# 2. 如果沒有,導入私鑰備份
gpg --import private_key_backup.asc
# 3. 或者重新生成密鑰
gpg --full-generate-key
# 4. 更新 Git 配置
git config --global user.signingkey NEW_KEY_ID問題 3:Inappropriate ioctl for device
症狀:
error: Inappropriate ioctl for device解決方案:
# macOS
brew install pinentry-mac
echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent
# Linux
sudo apt-get install pinentry-curses
echo "pinentry-program /usr/bin/pinentry-curses" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent問題 4:密鑰已過期
症狀:
key has expired解決方案:
# 1. 延長密鑰有效期
gpg --edit-key YOUR_KEY_ID
> expire
> save
# 2. 上傳更新後的公鑰
gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID
# 3. 更新 GitHub 上的公鑰
# 重新導出並替換 GitHub 上的公鑰
gpg --armor --export YOUR_EMAIL | pbcopy問題 5:Unverified 標識
症狀:
- Commit 顯示 "Unverified" 而非 "Verified"
原因和解決:
# 原因 1:郵箱不匹配
# 檢查 Git 郵箱
git config user.email
# 檢查 GPG 密鑰郵箱
gpg --list-keys
# 確保兩者一致
# 原因 2:公鑰未上傳到 GitHub
# 重新導出並添加到 GitHub
gpg --armor --export your@email.com
# 原因 3:使用了錯誤的密鑰
# 檢查當前使用的密鑰
git config user.signingkey
# 確保與 GitHub 上的公鑰對應問題 6:密碼每次都要輸入
解決方案:
# 配置密碼緩存
cat >> ~/.gnupg/gpg-agent.conf << EOF
default-cache-ttl 3600
max-cache-ttl 86400
EOF
# 重啟 agent
gpgconf --kill gpg-agent
# macOS 用戶使用 Keychain
brew install pinentry-mac
echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf最佳實踐
1. 密鑰備份
# 導出私鑰(重要!)
gpg --export-secret-keys --armor your@email.com > backup_private_key.asc
# 導出公鑰
gpg --export --armor your@email.com > backup_public_key.asc
# 導出吊銷證書
gpg --output revoke_cert.asc --gen-revoke your@email.com
# 安全存儲
# - 保存到加密的 USB 驅動器
# - 打印紙質備份
# - 存儲在密碼管理器中2. 密鑰輪換
# 建議輪換週期:
# - 個人使用:2-3 年
# - 企業環境:1 年
# - 高安全需求:6 個月
# 輪換步驟:
# 1. 生成新密鑰
gpg --full-generate-key
# 2. 更新 Git 配置
git config --global user.signingkey NEW_KEY_ID
# 3. 上傳新公鑰到 GitHub
# 4. 保留舊密鑰用於驗證歷史提交
# 5. 適時吊銷舊密鑰
gpg --edit-key OLD_KEY_ID
> revkey
> save3. 安全建議
# ✅ 應該做的:
# - 使用強密碼保護私鑰
# - 定期備份密鑰
# - 使用 4096 位密鑰(高安全場景)
# - 保持 GPG 軟件更新
# - 驗證他人公鑰指紋
# ❌ 不應該做的:
# - 不要分享私鑰
# - 不要在公共場合輸入密碼
# - 不要忽略密鑰過期警告
# - 不要使用過時的 GPG 版本
# - 不要在不信任的機器上使用私鑰總結
GPG 簽名為 Git 提交提供了強大的安全保障:
- ✅ 身份驗證:證明提交的真實性
- ✅ 完整性保護:防止內容篡改
- ✅ 可信標識:GitHub "Verified" 徽章
- ✅ 專業形象:提升代碼庫可信度
- ✅ 審計追蹤:不可抵賴的記錄
關鍵步驟回顧:
1. 安裝 GPG
2. 生成密鑰對
3. 導出公鑰並添加到 GitHub
4. 配置 Git 使用 GPG 簽名
5. 測試提交併驗證下一步學習:
開始使用 GPG 簽名,讓你的代碼提交更加安全可靠!🔐✨