配置 GitHub SSH 签名和认证密钥


官方文档:通过 SSH 连接到 GitHub

安装 Git

Git for Windows 安装过程详解

个人选择:

PixPin_2025-07-28_12-15-56.png|300

PixPin_2025-07-28_12-16-26.png|300

PixPin_2025-07-28_12-16-40.png|300

启用 OpenSSH Auth Agent 服务

因为安装中选择了 Use external OpenSSH,要启用 SSH Agent 系统服务。

根据名称或者描述找到这个服务,

image.png|300

image.png|300

也可以命令直接开启:

# 先获取服务,并设置成自动
Get-Service ssh-agent | Set-Service -StartupType Automatic
# 首次启动服务
Start-Service ssh-agent

生成密钥

私钥没有后缀名,公钥后缀名为 .pub

检查是否存在 SSH 密钥:dir $env:USERPROFILE\.ssh

查看已加载的密钥:ssh-add -l

从 SSH-Agent 中移除所有已添加密钥:ssh-add -D

1. 生成认证密钥(Authentication Key)

打开 PowerShell 7,进入 $HOME\.ssh\ 目录执行以下命令:

ssh-keygen -t ed25519 -f "$HOME\.ssh\认证密钥名字" -C "注释,可选,可后加"

默认保存到 $HOME\.ssh\。还配套生成了认证的公钥:认证密钥名字。pub

按需设置查看私钥的 Passphrase,就是密码,建议设置以提高安全性。

2. 生成签名密钥(Signing Key)

同上,生成签名密钥:

ssh-keygen -t ed25519 -f "$HOME\.ssh\签名密钥名字" -C "注释,可选,可后加"

将私钥添加到 SSH Agent

# 添加两种私钥
ssh-add .\.ssh\认证私钥
ssh-add .\.ssh\签名私钥

将公钥添加到 GitHub

  1. 登录 GitHub 网页 SettingsSSH and GPG keysNew SSH Key

  2. Title: 取个能分辨的

  3. Key Type: 跟密钥的用途走

  4. 粘贴公钥内容,末尾不要有空格和换行。

  5. 保存,Add SSH Key

配置 Git 使用 SSH 签名密钥

设置 Git 全局配置,配置文件路径:‪ C:\Users\用户名\.gitconfig

# Git 签名用户
git config --global user.name "昵称"
# Git 签名邮箱
git config --global user.email "your_email@example.com"
# 指定私钥,GitHub说是要公钥路径,就按公钥配置。网上有人教用私钥路径
git config --global user.signingkey .\.ssh\签名密钥.pub
# 或者用
git config --global user.signingkey "C:\Users\用户名\.ssh\签名密钥.pub"
# 指定使用 SSH 签名
git config --global gpg.format ssh
# 自动签名所有提交
git config --global commit.gpgsign true
# 自动签名版本发布的标签
git config --global tag.gpgsign true

重要提示: 尽管 user.signingkey 指向的是公钥,但 Git 会使用 SSH Agent 中加载的相应 私钥 来创建签名。请确保 SSH Agent 正在运行并且已加载您的私钥。

.gitconfig 具体配置:

[user]
    name = 名字
    email = 邮箱
    signingkey = ~/.ssh/GitHubSigningKey.pub
[gpg]
    format = ssh
[commit]
    gpgsign = true
[tag]
    gpgsign = true

如使用多种密钥,则要禁用自动签名

git config --global --unset commit.gpgsign
git config --global --unset tag.gpgsign

验证密钥

GitHub 的 SSH 密钥公钥指纹,会记录在‪C:\Users\用户名. ssh\known_hosts

验证命令:ssh -T git@github.com

成功会显示:Hi *** ! You’ve successfully authenticated, but GitHub does not provide shell access.

出错才配置

如报错下面这个,可使用 ssh -T -v git@github.com 排查

PS C:\Users\用户名> ssh -T git@github.com
CreateProcessW failed error:2
posix_spawnp: No such file or directory

C:\Users\用户名\.ssh\config 添加如下配置:

Host github.com
  User git
  ProxyCommand connect -S 127.0.0.1:7890 %h %p

要使用 connect 参数,要确保 connect.exe 在系统环境的 Path 路径里:

C:\Program Files\Git\mingw64\bin,具体取决于 Git 的安装路径。

成功如图:

image.png|300

验证签名状态

新开一个 Git 仓库,做一次提交,使用 git log --show-signature,应看到 Good “git” signature for ***。

如果显示:error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification

就要创建 SSH 签名信任文件(allowed_signers)

allowed_signers 是一个 SSH 签名信任列表文件,用于告诉 Git 哪些 SSH 公钥是可信的,可以用于验证提交或标签的签名。它是 Git 在使用 SSH 密钥进行签名时必需的一个配置文件。

allowed_signers 是本地验证工具,用于在本地确认提交是否由可信密钥签名。而 GitHub 通过你账户中上传的 SSH 签名公钥自动验证提交的合法性。

.ssh 目录下创建 allowed_signers

# 创建并编辑文件
code "$HOME\.ssh\allowed_signers"

添加你的签名公钥与邮箱绑定关系,打开 签名密钥.pub 文件,复制出内容,再进行如下调整:

格式:邮箱地址 <空格> namespaces="git" <空格> 公钥类型 <空格> 公钥 base64 编码

示例:my@mail.com namespaces="git" ssh-ed25519 (在此处粘贴实际公钥字符串)

allowed_signers 中的邮箱必须与提交使用的 user.email 完全一致

namespaces="git" 的作用

这个 namespaces="git" 并不是 SSH 协议本身的特性,而是 Git 在处理 SSH 签名时引入的一个约定。它的主要作用是:

  1. 明确指定用途: 告诉 Git 这个密钥是专门用于验证 Git 提交或标签签名的。这意味着,即使同一个 SSH 公钥在其他上下文中(例如,作为 SSH 登录凭据)被信任,它也只有在 namespaces="git" 声明时才会被 Git 视为有效的签名密钥。

  2. 增强安全性: 防止密钥的意外或恶意滥用。设想一下,如果您的 SSH 登录密钥不小心泄露,攻击者可能会尝试用它来伪造 Git 提交签名。通过 namespaces="git",Git 会强制要求签名密钥必须明确声明其 Git 签名用途,从而增加了安全层。

  3. 区分密钥用途: 在一些复杂的场景中,用户可能希望同一个 SSH 密钥仅用于登录 SSH 服务器,而不用来签名 Git 提交,或者反之。namespaces="git" 提供了这种细粒度的控制

配置 Git 使用 allowed_signers

git config --global gpg.ssh.allowedSignersFile "$HOME\.ssh\allowed_signers"

结果:

[gpg "ssh"]
    allowedSignersFile = C:\\Users\\用户名\\.ssh\\allowed_signers

再做一次提交后验证。

GPG 签名 vs SSH 签名的核心区别

特性GPG 签名SSH 签名
密钥管理需独立生成 GPG 密钥,与 SSH 密钥分离复用现有的 SSH 密钥(认证 + 签名一体化)
配置复杂度复杂(需安装 GPG 工具,配置路径)简单(Git 2.34+ 原生支持)
平台支持广泛支持(GitHub, GitLab 等)较新平台支持(GitHub 全支持,GitLab 需 ≥15.7)
密钥吊销通过 GPG 密钥吊销证书依赖平台删除 SSH 公钥
签名验证流程需上传 GPG 公钥到平台需上传 SSH 公钥到平台并启用签名权限
人类可读信息包含姓名、邮箱、有效期等元数据仅包含密钥指纹,元数据较少
与 CI/CD 集成需处理 GPG 代理和密码可直接复用现有 SSH 密钥(无需密码时更便捷)
跨平台兼容性所有版本 Git 均支持仅 Git ≥ 2.34 支持

如何选择?

  • 选 SSH 签名

    • 已有 SSH 密钥,追求简单配置。
    • 项目使用 Git 2.34+ 且平台支持(如 GitHub)。
    • 希望统一认证和签名流程。
  • 选 GPG 签名

    • 需要更详细的签名元数据(如有效期)。
    • 项目需兼容旧版 Git 或旧平台(如自建 GitLab <15.7)。
    • 需独立的签名密钥管理(如吊销证书)。

.gitconfig.ssh\config 有什么区别

1. .gitconfig 文件

  • 作用: Git 的全局配置文件,用于设置 Git 相关的全局参数(如用户名、邮箱、别名、默认编辑器等)。
    • 适用场景
    • 定义 Git 提交时的用户名和邮箱。
    • 设置 Git 命令的快捷别名(如 git st 代替 git status)。
    • 配置 Git 使用的文本编辑器(如 VS Code)。

2. .ssh\config 文件

  • 作用: SSH 客户端的连接配置文件,用于管理 SSH 连接到不同主机的参数(如密钥路径、端口、代理等)。
  • 适用场景
    • 配置通过代理或特定端口连接服务器。
    • 为 GitHub 指定使用特定的 SSH 密钥(解决多密钥冲突问题)。
    • 自定义 SSH 连接别名(如 ssh my-server 代替 ssh admin@192.168.1.100)。

对比总结

特性.gitconfig.ssh\config
所属工具GitSSH 客户端
配置内容Git 全局行为(用户信息、别名等)SSH 连接参数(主机、密钥、端口等)
影响范围所有 Git 操作所有 SSH 连接
典型配置项user.name, alias, core.editorHost, IdentityFile, Port, Proxy
是否需要权限无需特殊权限私钥文件需设置严格权限(如 600

常见误区

  1. 混淆使用场景

    • 若 Git 仓库使用 SSH 协议(如 git@github.com:user/repo.git),SSH 配置会影响 Git 的认证方式,但 Git 本身的提交行为由 .gitconfig 控制。
    • 例如:.ssh\config 指定 GitHub 使用密钥 A,而 .gitconfig 控制提交者邮箱。
  2. 路径格式问题

    • .ssh\config 中,路径建议使用 ~/.ssh/key 格式(如 IdentityFile ~/.ssh/id_ed25519),避免 Windows 反斜杠 \ 转义问题。

总结

  • .gitconfig:控制 Git 工具的行为(如提交信息、别名)。
  • .ssh\config:管理 SSH 连接细节(如密钥、端口、代理)。 两者各司其职,共同协作完成 Git over SSH 的完整流程。