簽章 Git 提交

簽章 Git 提交

GPG 全名為 The GNU Privacy Guard,又稱 GnuPG,可以用來對訊息或檔案進行加密(encrypt)或簽章(sign)。且可以和 Git 整合,用來簽章 Git 的提交內容,確保是由本人提交,而非被竄改或仿冒提交。

安裝 GPG

Windows

Windows 環境中現在在 Git Bash 已經內建了 GPG,安裝 Git 的時候就會安裝好 GPG 了。

不過也可以獨立安裝 Gpg4win,還附有一個 GUI 介面的 金鑰管理員(Kleopatra) 與 Outlook 外掛程式,如果你需要還是可以安裝的。

雖然可以不用安裝 gpg,但還是需要設定 Git 的 gpg.program 選項設定,指定 gpg.exe 所在路徑:

Terminal window
git config --global gpg.program "C:\Program Files\Git\usr\bin\gpg.exe"

Bash

如果有使用 Bash,需要增加以下指令到 ~/.profile~/.bashrc~/.bash_profile 檔案中:

Terminal window
export GPG_TTY=$(tty)
gpgconf --launch gpg-agent

否則在執行 gpg 簽章時會發生以下錯誤:

error: gpg failed to sign the data
fatal: failed to write commit object

GPG 使用方式

安裝好之後就可以開始使用了。

建立 GPG 金鑰組

Terminal window
gpg --full-generate-key

建立過程中,需要輸入以下:

  1. Please select what kind of key you want: 輸入 Enter 選預設值 (9) ECC (sign and encrypt)
  2. Please select which elliptic curve you want: 輸入 Enter 選預設值 (1) Curve 25519
  3. Please specify how long the key should be valid: 輸入 2y
  4. 輸入你的 GitHub 的名稱和 E-mail
  5. 輸入 O (即 OK)
  6. 設定密碼

看到如下畫面就是建立成功了:

gpg: revocation certificate stored as '/c/Users/Lucas/.gnupg/openpgp-revocs.d\7144F0FE70DA28DE2428982FAFA8022C0E4062EF.rev'
public and secret key created and signed.
pub ed25519 2021-04-08 [SC] [expires: 2023-04-08]
DC279878969CA746899B02FFAE57F5023B001577
uid Lucas Yang <yangchenshin77@gmail.com>
sub cv25519 2021-04-08 [E] [expires: 2023-04-08]

查詢 GPG 金鑰組

列出公開金鑰資訊:

Terminal window
gpg --list-keys
gpg --list-keys --keyid-format SHORT
gpg --list-keys --keyid-format LONG

列出私密金鑰資訊:

Terminal window
gpg --list-secret-keys
gpg --list-secret-keys --keyid-format SHORT
gpg --list-secret-keys --keyid-format LONG

如果我們要簽章 Git 提交,就必須先取得金鑰 ID:

Terminal window
gpg --list-secret-keys --keyid-format SHORT
[keyboxd]
---------
sec rsa4096/0E4062EF 2021-04-08 [SC]
7144F0FE70DA28DE2428982FAFA8022C0E4062EF
uid [ultimate] Lucas Yang <yangchenshin77@gmail.com>
ssb cv25519/5F50EFE6 2021-04-08 [E]

上述訊息中,sec 就是 secret (私密金鑰),而 7144F0FE70DA28DE2428982FAFA8022C0E4062EF 就是完整的金鑰 ID,可以用簡短的金鑰代替,也就是 0E4062EF,之後的操作都會用到這段 ID。

設定 Git 提交進行 GPG 簽章

設定預設的 GPG 金鑰:

Terminal window
git config --global user.signingkey 0E4062EF

然後就可以在 Git 提交 (commit) 或標籤 (tag) 時進行 GPG 簽章:

Terminal window
git commit -S
git tag -s

當然也可以設定自動簽章:

Terminal window
git config --global commit.gpgSign true
git config --global tag.gpgSign true

顯示 Git 簽章資訊

顯示含有簽章資訊的 Git 的指令:

Terminal window
git log --show-signature
commit aa993b7b69b47a6bf9d23cacf56e00139f3907a0 (HEAD -> main, origin/main)
gpg: Signature made 2021/4/8 <A4>U<A4><C8> 04:54:57 <A5>x<A5>_<BC>зǮɶ<A1>
gpg: using RSA key CB8E694EB798BFED6FA1C2DC88D3F62D215D5306
gpg: Good signature from "Lucas Yang <yangchenshin77@gmail.com>" [ultimate]
Author: Lucas Yang <yangchenshin77@gmail.com>
Date: Thu Apr 8 16:54:57 2021 +0800
Formatting

設定 GitHub 帳號的 GPG 金鑰

直接將 GPG 公鑰輸出在「命令提示字元」中:

Terminal window
gpg --armor --export 0E4062EF

並複製公鑰,到 GitHub 的 SSH and GPG keys 設定,新增一個 GPG 金鑰。

設定 VS Code

在 VS Code 增加 git.enableCommitSigning,之後 VS Code 提交 Git commit 時都會加上簽章:

settings.json
{
"git.enableCommitSigning": true,
}

遷移 GPG 金鑰組到其他電腦

匯出公鑰:

Terminal window
gpg --armor --export 0E4062EF > gpg-pub.asc

匯出私鑰,這裡應該會提示輸入密碼:

Terminal window
gpg --armor --export-secret-keys 0E4062EF > gpg-sc.asc

確認一下公鑰和私鑰:

Terminal window
ls -l gpg*.asc

然後把金鑰組移到新電腦上。到新電腦之後就開始匯入的操作:

Terminal window
gpg --import gpg-pub.asc

匯入私鑰,這裡應該會提示輸入密碼:

Terminal window
gpg --import gpg-sc.asc

最後記得要在舊電腦上刪除乾淨金鑰組。

刪除 GPG 金鑰組

如果公鑰私鑰都在同一台電腦,必須先刪除私鑰,才能刪除相對應的公鑰。也可以直接刪除私鑰就好,公鑰保留。

刪除私鑰:

Terminal window
gpg --delete-secret-key 0E4062EF

刪除公鑰:

Terminal window
gpg --delete-key 0E4062EF

延長 GPG 金鑰組的有效期限

Terminal window
gpg --edit-key 0E4062EF

進入互動介面後,輸入 expire,然後選擇新的有效期限比如 2y,最後輸入 save 就完成了。

參考資料