Git 签名

通常 Push 代码到远程托管平台(GitHub,Gitlab,Gitee 等),需要提前在托管平台上传我们 Git 账户的公钥(*.pub),平台使用上传的公钥来验证身份(本地的 Git 私钥与平台上的公钥配对,以确保你有权限读写该仓库),该验证只会在 Push 时进行检查
为什么要签名
虽然对 Push 做了检查,但依然不够安全,因为任何拥有该仓库权限的人,都可以在 commit/tag 时使用 git config user.name "假的用户名", git config user.email "假的邮箱地址" 命令来伪造提交者用户信息,这样我们根本无法追溯提交者的身份,所以我们需要给 commit/tag 签名,签名的目的是确保提交的代码在传输和存储过程中没有被篡改,并验证提交者的身份,同时也保证代码的可追溯性
commit 签名是在本地,在使用 git commit 命令时进行签名,push 时会将你的签名信息,原封不动 push 到远程仓库
commit 签名只是用于验证这条 commit 来自于你本人,与是否有权限操作远程仓库无关
如何签名
可以使用 GPG、SSH 或 S/MIME,可以在本地对 commit/tag 进行签名。 这些 commit/tag 在 GitHub 上标示为已验证,便于其他人信任更改来自可信的来源
SSH、GPG、S/MIME 区别
- SSH 签名是最容易生成的,甚至可以将现有身份验证密钥上传到 GitHub 以用作签名密钥
- 生成 GPG 签名比生成 SSH 密钥复杂,但 GPG 具有 SSH 没有的功能,GPG 密钥可以在不使用时过期或撤销
- 较大型组织的环境中通常需要 S/MIME 签名
👍 SSH(常用)
SSH 签名验证需 Git 2.3.4 及以上版本
检查现有 SSH 密钥
| 1 | # 查看本地 ~/.ssh 路径现有密钥 | 
检查已有密钥列表已有 RSA 密钥,如果你已经有 SHA-2 算法生成 RSA 密钥 那么你可以 跳过 生产新 SSH 密钥,如果没有,为了安全,还是建议重新生成 SHA-2 算法生成 RSA 密钥
生产新 SSH 密钥
- 2022.03.15
- 在该日期 GitHub 删除旧的、不安全的密钥类型来提高安全性
- 自该日期起,不再支持 DSA 密钥 (ssh-dss)。 无法 在 github.com 上向个人帐户添加新的 DSA 密钥
 
- 2021.11.02
- 在该日期 之前 带有 valid_after 的 RSA 密钥 (ssh-rsa) 可以继续使用任何签名算法
- 在该日期 之后 生成的 RSA 密钥 必须 使用 SHA-2 签名算法。 一些较旧的客户端可能需要升级才能使用 SHA-2 签名
 
在生成 SSH 密钥时,我们可以给 SSH 密钥添加密码,也可以不添加密码,这里根据需要选择是否添加密码

- 执行 ssh-keygen -t ed25519 -C "Jerry.x@outlook.com"命令,这里的邮箱换成你的 GitHub 邮箱
- 确认密钥存放位置
- 如果不需调整(默认:/User/blade/.ssh/id_ed25519),可 Enter 键进入下一步
- 这里我重命名了密钥 /User/blade/.ssh/id_ed25519_test
 
- 如果不需调整(默认:
- 给密钥设置密码
- 如果无需设置,可 Enter 键进入下一步
- 如果需设置,输入密码即可
 
- 确认输入的密钥密码,和上一步输入内容一致
- 提示生成的密钥存放位置和指纹信息
如果密钥 设置了密码,需要将 SSH 密钥添加到 ssh-agent
在向 ssh-agent 添加新的 SSH 密钥管理密钥前,应该检查现有 SSH 密钥并生成新的 SSH 密钥
如果已安装 GitHub Desktop,可使用它克隆存储库,而无需处理 SSH 密钥
- 
在新的“管理员提升”__ PowerShell 窗口中,确保 ssh-agent 正在运行。 可以使用“使用 SSH 密钥密码”中的“自动启动 ssh agent”说明,或者手动启动它 1 
 2
 3# start the ssh-agent in the background 
 Get-Service -Name ssh-agent | Set-Service -StartupType Manual
 Start-Service ssh-agent
- 
在无提升权限的终端窗口中,将 SSH 私钥添加到 ssh-agent。 如果使用其他名称创建了密钥,或要添加具有其他名称的现有密钥,请将命令中的 id_ed25519 替换为私钥文件的名称 1 ssh-add c:/Users/YOU/.ssh/id_ed25519 
将 SSH 密钥添加到该代理时,应使用默认的 macOS ssh-add 命令,而不是使用通过 macports、homebrew 或某些其他外部来源安装的应用程序
- 
在后台启动 ssh 代理 1 
 2$ eval "$(ssh-agent -s)" 
 > Agent pid 59566根据您的环境,您可能需要使用不同的命令。 例如,在启动 ssh-agent之前,你可能需要通过运行sudo -s -H根访问,或者可能需要使用exec ssh-agent bash或exec ssh-agent zsh运行ssh-agent
- 
如果你使用的是 macOS Sierra 10.12.2 或更高版本,则需要修改 ~/.ssh/config文件以自动将密钥加载到ssh-agent中并在密钥链中存储密码- 
检查你的 ~/.ssh/config文件是否在默认位置
- 
如果文件不存在,请创建该文件 
- 
打开你的 ~/.ssh/config文件,然后修改文件以包含以下行。 如果您的 SSH 密钥文件与示例代码具有不同的名称或路径,请修改文件名或路径以匹配您当前的设置1 
 2
 3
 4
 5
 6
 7
 8Host github.com 
 # 如果看到了 Bad configuration option: usekeychain 错误,
 # 取消下一行注释,使用 IgnoreUnknown 配置
 # IgnoreUnknown UseKeychain
 AddKeysToAgent yes
 # 如果你选择不向密钥添加密码,应该省略 UseKeychain 行
 UseKeychain yes
 IdentityFile ~/.ssh/id_ed25519
 
- 
- 
将 SSH 私钥添加到 ssh-agent并将密码存储在密钥链中。 如果使用其他名称创建了密钥,或要添加具有其他名称的现有密钥,请将命令中的 id_ed25519 替换为私钥文件的名称1 ssh-add --apple-use-keychain ~/.ssh/id_ed25519 
- 
在后台启动 ssh 代理 1 
 2$ eval "$(ssh-agent -s)" 
 > Agent pid 59566根据您的环境,您可能需要使用不同的命令。 例如,在启动 ssh-agent之前,你可能需要通过运行sudo -s -H根访问,或者可能需要使用exec ssh-agent bash或exec ssh-agent zsh运行ssh-agent
- 
将 SSH 私钥添加到 ssh-agent 如果使用其他名称创建了密钥,或要添加具有其他名称的现有密钥,请将命令中的 id_ed25519 替换为私钥文件的名称 1 ssh-add ~/.ssh/id_ed25519 
除了上述的方式生成密钥,还有 为硬件安全密钥生成新的 SSH 密钥 方式,这里不做说明,可以移步官方文档查看
将 SSH 密钥添加到 GitHub 账户

其他更多设置可参考官方文档 新增 SSH 密钥到 GitHub 帐户
将签名密钥告诉 Git
- 如需全局配置:添加 --global参数
- 如果你有多个 Git 账号,推荐 按照不同的账号分别进行配置,具体可参考 Git 多账号配置 这篇文章
| 1 | # 1. 配置 Git 使用 SSH 对提交和标记签名 | 
配置可信公钥列表
| 1 | mkdir -p ~/.config/git | 
对 commit 签名
| 1 | # 1. 当本地分支中的提交更改时,请将 -S 标志添加到 git commit 命令 | 
对 tag 签名
注意:如果 Git 客户端配置为默认对提交进行签名,GitHub Desktop 仅支持提交签名
| 1 | # 1. 若要对标记进行签名,请将 -s 添加到 git tag 命令 | 
GPG
具体实践可参考官方文档 GPG 提交签名验证
S/MIME
S/MIME 签名验证需 Git 2.19 及以上版本
由于 S/MIME 用的比较少,这里就不做具体的演示,可参考 官方文档
验证签名
| 1 | # 查看一下本地签名信息 | 
问题
验证签名提示异常
如何给现有密钥更新密码
通过输入以下命令,您可以 更改 现有私钥 的密码而无需重新生成密钥对
| 1 | # 修改 id_ed25519 密钥密码 | 
参考
- Git 提交使用 SSH 签名和 GPG 签名验证
- SSH 提交签名验证
- GitHub commit 签名指南
- 维护代码的尊严:GPG签名让你的Git commit不再裸奔


