Skip to main content

关于提交签名验证

使用 GPG、SSH 或 S/MIME,可以在本地对标记和提交进行签名。 这些标签或提交在 GitHub 上被标记为已验证,这样其他人就可以确信这些更改来自可信来源。

关于提交签名验证

您可以在本地为提交和标签进行数字签名,以保证您所做更改的来源真实性,让其他人更加放心。 如果提交或标记具有可加密验证的 GPG、SSH 或 S/MIME 签名, GitHub 请标记提交或标记 “已验证”或“部分验证”。

存储库提交列表中提交的屏幕截图。 “已验证”以橙色边框突出显示。

对于大多数个人用户来说,使用 GPG 或 SSH 对提交进行签名是最佳选择。 在较大型组织的环境中通常需要 S/MIME 签名。 SSH 签名是最容易生成的。 您甚至可以将现有的身份验证密钥上传到 GitHub,同时将其用作签名密钥。 生成 GPG 签名密钥比生成 SSH 密钥更复杂,但 GPG 具有 SSH 所没有的功能。 GPG 密钥可以在不再使用时过期或撤销。 GPG 签名可能包含其已过期或被撤销的信息。

提交和标签具有以下验证状态,具体取决于您是否启用了警戒模式。 默认情况下未启用警戒模式。 有关如何启用警戒模式的信息,请参阅“显示所有提交的验证状态”。

对提交签名不同于提交签核。 有关签署提交的更多信息,请参阅 管理存储库的提交签字策略

默认状态

状态说明
已验证提交已签名且签名已成功验证。
未验证提交已签名,但签名无法验证。
无验证状态提交未签名。

持续的提交签名验证

无论选择哪种签名方式(GPG、SSH 还是 S/MIME),一旦提交签名经过验证,它将在其存储库网络中保持验证状态。 请参阅“了解仓库之间的连接”。

当提交被推送到 GitHub 时,如果其签名通过验证,系统会将验证记录与该提交一并存储。 该记录无法编辑且会一直存在,这样一来,即便签名密钥被轮换、撤销,或者参与者离开了组织,签名也能始终保持已验证状态。

验证记录包含一个时间戳,用于标记验证完成的时间。 此持久记录可确保已验证状态的一致性,为存储库内的参与提供稳定的历史记录。 可以通过将鼠标悬停在 GitHub 上的“已验证”徽章上,或通过 REST API 访问该提交(其中包含 verified_at 字段)来查看此时间戳。 请参阅“REST API 提交端点”。

持久提交签名验证适用于推送到 GitHub的新提交。 对于在此功能之前所做的任何提交,将在下次验证 GitHub提交签名时创建永久性记录,帮助确保在存储库历史记录中验证状态保持稳定且可靠。

记录即使在撤销和过期之后仍会保留

持久的提交签名验证反映的是提交在验证时的已验证状态。 这意味着,如果之后签名密钥撤销、过期或以其他方式更改,先前已验证的提交会依据初次验证时创建的记录保留其已验证状态。 GitHub 不会重新验证以前签名的提交,也不会追溯性地调整其验证状态,以响应密钥状态的更改。 组织可能需要直接管理密钥状态以符合其安全策略,特别是在计划频繁进行密钥轮换或撤销的情况下。

验证记录的范围限定在其存储库网络内

验证记录在存储库网络中是持久存在的,这意味着如果同一个提交再次被推送到同一个存储库或其任何分支,现有的验证记录会被重复使用。 这使得 GitHub 能够在相关仓库之间保持一致的已验证状态,而不必在该提交每次出现在该网络中时都重新进行验证。 这种持久性强化了在存储库网络内提交的所有实例中对提交真实性的统一且可靠的认知。

变基和合并的签名验证

在拉取请求上使用“变基与合并”时,请务必注意,头分支中的提交将添加到基分支,无需提交签名验证。 使用此选项时,GitHub 会使用原始提交的数据和内容创建修改的提交。 这意味着 GitHub 未真正创建此提交,因此无法将其签名为通用系统用户。 GitHub 无权访问提交者的专用签名密钥,因此无法代表用户对提交进行签名。

解决方法是在本地进行变基和合并,然后将更改推送到拉取请求的基分支。

有关详细信息,请参阅“关于GitHub上的合并方法”。

启用了警戒模式的状态

状态说明
已验证提交已签名,签名已成功验证,并且提交者是启用警戒模式的唯一作者。
部分验证提交已签名,签名已成功验证,但提交的作者:a) 不是提交者,并且 b) 已启用警戒模式。 在这种情况下,提交签名并不保证作者的同意,因此提交只得到部分验证。
未验证以下任一项是正确的:
- 提交已签名,但签名无法验证。
- 提交未签名,并且提交者已启用警戒模式。
- 提交未签名,并且创建者已启用警戒模式。

仓库管理员可以在分支上强制执行必要的提交签名,以阻止所有未签名和未验证的提交。 有关详细信息,请参阅“关于受保护分支”。

你可以在 GitHub 上检查已签名提交或标记的验证状态,并查看提交签名未验证的原因。 有关详细信息,请参阅“检查您的提交和标签签名验证状态”。

GitHub 将自动使用 GPG 对使用 Web 界面所做的提交进行签名。 由 GitHub 签名的提交将显示为已验证状态。 可以使用 https://github.com/web-flow.gpg 提供的公钥在本地验证签名。

你也可以选择在 GitHub 中使用 GitHub Codespaces GPG 为你创建的提交签名。 有关为代码空间启用 GPG 验证的详细信息,请参阅 管理 GitHub Codespaces 的 GPG 验证

GPG 提交签名验证

您可以使用 GPG 通过自己生成的 GPG 密钥对提交进行签名。

GitHub 使用 OpenPGP 库确认你在本地签名的提交和标签是否可根据你添加到 GitHub.com 账户中的公钥进行加密验证。

若要使用 GPG 为提交签名,并让这些提交在 GitHub 上显示为已验证,请按照以下步骤操作:

  1. 检查现有 GPG 密钥
  2. 生成新 GPG 密钥
  3. 向 GitHub 帐户添加 GPG 密钥
  4. 将你的签名密钥告诉 Git
  5. 签名提交
  6. 签署标签

SSH 提交签名验证

可以使用 SSH 通过自己生成的 SSH 密钥对提交进行签名。 有关详细信息,请参阅 Git 参考文档user.Signingkey。 如果已使用 SSH 密钥进行身份验证 GitHub,还可以再次上传同一密钥以用作签名密钥。 可以添加到帐户的签名密钥数没有限制。

GitHub 使用开源 Ruby 库 ssh_data 来确认你在本地签名的提交和标签是否可通过你添加到 GitHub.com 账户中的公钥进行加密验证。

注意

SSH 签名验证可用于 Git 2.34 或更高版本。 若要更新 Git 版本,请参阅 Git 网站。

若要使用 SSH 为提交签名,并让这些提交在 GitHub 上通过验证,请按以下步骤操作:

  1. 检查现有 SSH 密钥
  2. 生成新的 SSH 密钥
  3. 向 GitHub 帐户添加 SSH 签名密钥
  4. 将你的签名密钥告诉 Git
  5. 签名提交
  6. 签署标签

S/MIME 提交签名验证

您可以使用 S/MIME 使用由您的组织颁发的 X.509 密钥来为提交进行签名。

GitHub 使用 Debian ca-certificates 软件包(与 Mozilla 浏览器使用的信任存储相同),来确认您在本地签名的提交和标签能够根据受信任根证书中的公钥进行加密验证。

注意

S/MIME 签名验证可用于 Git 2.19 或更高版本。 若要更新 Git 版本,请参阅 Git 网站。

若要使用 S/MIME 对提交进行签名,并让这些提交在 GitHub 上显示为已验证,请按照以下步骤操作:

  1. 将你的签名密钥告诉 Git
  2. 签名提交
  3. 签署标签

你无需将你的公钥上传到 GitHub。

机器人签名验证

GitHub Apps组织和需要提交签名的组织可以使用机器人对提交进行签名。 如果提交或标记具有可加密验证的机器人签名, GitHub 则将提交或标记标记为已验证。

仅当请求已验证并认证为 GitHub App 或机器人,且不包含任何自定义作者信息、自定义提交者信息或自定义签名信息(例如通过 Commits API 发起的请求)时,机器人的签名验证才会生效。

延伸阅读