连接 GitHub 时提示 $SSH_SK_PROVIDER did not resolve
结论
$SSH_SK_PROVIDER did not resolve 和 known_hosts2: No such file or directory 通常不会导致这次认证失败。
排查重点是 Git 实际调用的 SSH 客户端、该客户端能否找到正确的私钥,以及 GitHub 是否接受对应的公钥。使用 OpenSSH 时,Pageant 一般不参与认证。
两条调试信息是什么意思
$SSH_SK_PROVIDER did not resolve
SSH_SK_PROVIDER 用于指定 FIDO/U2F 安全密钥的 provider。使用普通的 RSA、ECDSA 或 Ed25519 密钥时,这项功能与当前认证无关。
provider 解析失败后,OpenSSH 会禁用安全密钥支持并继续连接。后续日志中已经出现:
debug1: Connection established.
debug1: Authenticating to github.com:22 as 'git'
网络连接和 SSH 协议协商仍在正常进行。只有使用硬件安全密钥时,才需要关注 SSH_SK_PROVIDER 环境变量。
known_hosts2 不存在
OpenSSH 会依次检查多个主机密钥文件,包括 known_hosts 和可选的 known_hosts2。如果第二个文件不存在,详细日志会记录一次 fopen 失败,但连接不会因此中断。
主机密钥有问题时,通常会看到:
Host key verification failed.
当前错误是:
Permission denied (publickey).
这说明客户端已经连接到 GitHub,但没有提供 GitHub 认可的公钥。
确认 Git 使用了哪个 SSH
Windows 上可能同时装有多套 SSH:
- Windows 自带的 OpenSSH
- Git for Windows 附带的 OpenSSH
- PuTTY 的
plink.exe - Git Extensions 指定的 SSH 程序
先在 PowerShell 中检查:
where.exe git
where.exe ssh
Get-Command ssh -All
git config --show-origin --get core.sshCommand
Get-ChildItem Env:GIT_SSH*
如果配置过 GIT_SSH、GIT_SSH_COMMAND 或 core.sshCommand,Git 使用的可能不是命令行测试时调用的那个 ssh.exe。
也可以让 Git 打印实际执行的命令:
$env:GIT_TRACE = "1"
git ls-remote origin
Remove-Item Env:GIT_TRACE
从输出中可以确认 Git 调用了哪个 SSH 程序。Git Extensions 也应使用同一套 OpenSSH,以免命令行测试正常,图形界面却仍在调用另一套客户端。
检查 OpenSSH 能否找到私钥
复制项目和其中的 .git 目录,只会带走远程仓库地址、分支及提交记录。用户目录中的 SSH 私钥、~/.ssh/config 和 agent 状态不会随项目一起迁移。
先查看密钥文件:
Get-ChildItem "$env:USERPROFILE\.ssh"
常见的私钥名称有:
id_ed25519
id_rsa
同名的 .pub 文件是公钥。认证时要使用不带 .pub 后缀的私钥。
如果使用 ssh-agent,先查看已经加载的密钥:
ssh-add -l
如果没有任何 identity,添加私钥后再次检查:
ssh-add "$env:USERPROFILE\.ssh\id_ed25519"
ssh-add -l
这里需要运行的是 Windows 的 ssh-agent 服务:
Get-Service ssh-agent
Start-Service ssh-agent
如果服务已被禁用,需要在管理员 PowerShell 中修改启动方式:
Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent
Start-Service 和 Set-Service 是否需要管理员权限,取决于当前系统策略。
跳过 agent,直接指定私钥测试
直接指定密钥,可以判断问题来自密钥本身,还是 agent、Git Extensions 等中间环节:
ssh -i "$env:USERPROFILE\.ssh\id_ed25519" `
-o IdentitiesOnly=yes `
-vT git@github.com
认证成功后,GitHub 通常会提示身份验证成功,但不提供 shell 访问。ssh -T 返回非零状态也不一定表示认证失败,应以具体输出为准。
如果仍然失败,使用更详细的日志:
ssh -vvv -i "$env:USERPROFILE\.ssh\id_ed25519" `
-o IdentitiesOnly=yes `
-T git@github.com
重点查看:
Offering public key:
Server accepts key:
日志通常对应以下情况:
- 没有
Offering public key:OpenSSH 没有读取或选择该私钥。 - 有
Offering public key,但没有Server accepts key:GitHub 账户中没有对应的公钥,或者该账户无权访问仓库。 - 有
Server accepts key,随后要求输入私钥密码:密钥已经匹配,需要输入创建私钥时设置的 passphrase。
核对 GitHub 上的公钥
查看本地公钥的指纹:
ssh-keygen -lf "$env:USERPROFILE\.ssh\id_ed25519.pub"
也可以从私钥重新导出公钥,避免选错 .pub 文件:
ssh-keygen -y -f "$env:USERPROFILE\.ssh\id_ed25519"
将输出与 GitHub 账户中 SSH key 的内容或指纹进行核对。常见问题有:
- 公钥添加到了另一个 GitHub 账户。
- GitHub 上保存的是旧公钥,本机使用的却是新私钥。
- 复制公钥时内容被截断。
- 上传了与当前私钥不匹配的
.pub文件。 - 组织启用了额外的访问控制,新密钥还未获得组织授权。
不要将私钥上传到 GitHub,也不要通过聊天、工单或邮件发送私钥。GitHub 上应保存一整行公钥,格式类似:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... comment
固定 GitHub 使用的密钥
如果显式指定私钥后可以正常连接,可以在 %USERPROFILE%\.ssh\config 中固定这项配置:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
然后重新测试:
ssh -T git@github.com
GitHub 的 SSH 用户名固定为 git,不能改成 GitHub 登录名。
有多个 GitHub 账户时,可以通过别名区分:
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
对应的远程地址需要改为:
git remote set-url origin git@github-work:OWNER/REPOSITORY.git
不要混用 OpenSSH 和 Pageant
Pageant 是 PuTTY 工具链的密钥代理,主要为 plink.exe 提供密钥。Git Extensions 使用 OpenSSH 时,通常无须启动 Pageant。OpenSSH 使用 ssh-agent 和 OpenSSH 格式的私钥。
选择 PuTTY 时,应配套使用:
plink.exe- Pageant
- PuTTY 能识别的密钥格式,例如
.ppk
选择 OpenSSH 时,应配套使用:
ssh.exessh-agent- OpenSSH 能读取的私钥
OpenSSH 可能无法识别直接交给它的 PuTTY .ppk 文件。可以用 PuTTYgen 转换密钥,也可以重新生成 OpenSSH 密钥。两套客户端应各自使用对应的密钥和配置。
检查仓库地址和访问权限
SSH 认证成功后,核对当前仓库的远程地址:
git remote -v
再测试是否能读取远程引用:
git ls-remote origin
SSH 地址应类似:
git@github.com:OWNER/REPOSITORY.git
如果 ssh -T git@github.com 已经认证成功,而 git ls-remote origin 仍然失败,问题通常出在仓库层面:
OWNER/REPOSITORY是否写错;- 仓库是否已经移动、删除或重命名;
- 当前 GitHub 账户是否有权访问该私有仓库;
- 组织是否要求为新 SSH key 单独授权。
建议按以下顺序排查:先确认 Git 调用的 ssh.exe,再显式指定私钥测试,然后查看详细日志中的 Offering public key,最后核对 GitHub 上的公钥和仓库权限。无需创建 known_hosts2,$SSH_SK_PROVIDER 提示通常也不是普通 SSH 密钥认证失败的原因。
备注:内容仅供参考。
