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不再裸奔