☰
GitHub配置SSH Key完全指南:从生成密钥到免密推送与避坑
2026/10/15 5:38:48 网站建设 项目流程

每次 git push 都要输入用户名和密码,输错一次还要重新来,赶上手边密码管理器没解锁,整个人能卡在那半分钟——这种体验,但凡用过 GitHub 的开发者应该都不陌生。后来我花十来分钟配好了 SSH Key,从此 push、pull、fetch 全程无感,换电脑重装系统之后也能直接连上。这篇文章我就围绕“GitHub 配置 SSH Key”这件事,把从生成密钥、添加到账号、验证连通,再到我踩过的各种坑完整捋一遍。适合刚接触 Git、一直被 HTTPS 密码方式折磨的新手,也适合想搞懂密钥原理和排查思路的进阶用户。

1. 为什么要跟密码“分手”:HTTPS 和 SSH 的真实体验差异

GitHub 给仓库提供了两种远程连接方式:HTTPS 和 SSH。很多新手在 clone 仓库时,看到页面最显眼的位置是https://github.com/xxx/xxx.git,直接就复制了,于是后面 push 的时候就被反复要求输入账号密码。问题是 GitHub 早就取消了“账号密码直接 push”的方式,现在用 HTTPS 必须填写 Personal Access Token(个人访问令牌)。那个 token 是一串几十位的随机字符,每次输入都容易出错,复制粘贴稍不注意还会带个换行符,然后又是一轮报错。

我见过不少同事就是这样被逼疯的:明明 Git 操作都会,就是每次 push 都卡在认证环节。他们后来问我怎么解决,我说你先跟我一样把 SSH 配好。配置完成之后,本地生成的公私钥会替你完成身份认证,Git 不会再来问你密码,推送代码就像在本地操作一样顺滑。

对比一下两条路线的使用场景,能帮助你做选择:

对比项HTTPSSSH
首次配置生成 token 较繁琐生成密钥并上传公钥,约 10 分钟
日常推送每次需要 token 或缓存凭证配置完成后无需输入任何东西
安全机制用户名 + 一次性令牌非对称加密密钥对
适合场景偶尔 clone 公开仓库自己长期维护、每天推送的项目
网络限制一般 443 端口,穿透性强22 端口,某些内网要额外处理

我的建议是:临时 clone 一下别人的开源项目,用 HTTPS 完全没问题;但只要是你会持续开发、每天都要 push 的仓库,趁早换成 SSH。这个底层逻辑很简单——你在 GitHub 上存的不是你自己的私钥,而是公钥;验证动作发生在本地签名和远端验签之间,所有凭据都不需要每次重新输入。一次配置,长期受用,这个时间投入非常划算。

另外提一句,HTTPS 也不是完全不能用,Git 本身有凭据助手可以把 token 存进系统钥匙串,但那个方案在 Windows 上偶尔会弹一堆奇怪的窗口,在 Linux 上配置起来也分桌面环境和服务器环境,远不如 SSH 干净利落。

2. SSH Key 到底在干什么:一次提交背后的密钥握手逻辑

要理解 SSH Key 的工作方式,可以先把它想成一把锁和一把钥匙。公钥就是那把锁,你把它交给你要连接的服务器,比如 GitHub;私钥就是你手里的钥匙,永远只放在自己的电脑里。当你执行git push时,本地 Git 用私钥对请求做签名,GitHub 收到后用之前存好的公钥去验证。能对上,就认定这个请求来自你本人,于是放行。

这个过程中最关键的一点是:私钥永远不应该离开你的机器。GitHub 后台虽然保存了你的公钥,但即使公钥泄露,别人也只能验证你的身份,无法伪造你的签名,因为签名需要私钥才能完成。这跟密码完全不同——密码一旦泄露就等于账号失守,而公钥泄露几乎不构成风险。这也是 SSH 相比 HTTPS 更“省心”的根本原因。

另外,SSH 连接还会做一层 Host Key 校验。你第一次ssh -T git@github.com时,终端会提示确认 GitHub 服务器的指纹,这就是在防止中间人攻击。如果你曾经看到过REMOTE HOST IDENTIFICATION HAS CHANGED这类警告,说明你连接的那台服务器指纹和之前记录的不一致,这时候千万别直接跳过,先想想是不是你连错了地址。

现在生成密钥时算法选择也很重要。目前主流是 ed25519 和 RSA 两种,我用过很长一段时间的 RSA,后来换成了 ed25519,感受非常明显:

  • ed25519:密钥长度短(公钥就一行),生成速度快,安全性在现代标准下足够高,GitHub 官方也推荐这种算法。
  • RSA:兼容性最好,但为了达到同级安全水平,一般要用 4096 位,公钥又长又啰嗦。

除非你要连接的服务器特别老,只支持 RSA,否则新生成的密钥我都建议直接选 ed25519。ssh-keygen 本身是一个广泛使用的密钥生成工具,这个过程中会问你存放路径和 passphrase,下面一节我会把每一步拆开讲。

整个密钥握手的逻辑并不复杂:GitHub 存公钥,你本地产私钥签名,双方各自持有“一半”信息,合作完成认证。理解这一点之后,后面所有配置工作其实都是顺理成章的事——你只是把你的公钥放到了 GitHub 后台的某个位置,然后把私钥交给了本地的 ssh-agent 保管。

3. 一条龙配置实操:从生成密钥到 GitHub 后台登记

3.1 先检查机器上有没有旧钥匙

很多人家里已经留着一把老钥匙,自己都忘了。在动手生成新密钥前,先看一眼本机现有的:

ls -al ~/.ssh

如果看到id_ed25519或id_rsa这类文件,说明这台机器之前已经生成过密钥。这时候你有两个选择:一是直接复用旧密钥,前提是你还记得它的 passphrase,而且确定没有泄露过;二是重新生成一把新密钥。我的建议是,如果不确定旧密钥是否安全,就重新生成,然后把旧公钥从 GitHub 后台删掉,别留一堆自己都不知道什么时候建的 key 挂在账号里。

~/.ssh目录下常见的文件包括:

文件作用
id_ed25519私钥,绝对不能泄露
id_ed25519.pub公钥,要粘贴到 GitHub
known_hosts记录连接过的服务器指纹
config多主机连接配置,后面会讲

3.2 生成新的密钥对

打开终端,执行:

ssh-keygen -t ed25519 -C "你的邮箱"

简单解释一下这几个参数:

  • -t ed25519:指定密钥算法,我前面讲了,优先选 ed25519。
  • -C "你的邮箱":添加备注,方便在 GitHub 后台认出这把 key 是哪台电脑的。这里的邮箱只是注释,并不一定要和 GitHub 账号邮箱完全一致。
  • 如果不加-f指定路径,默认会生成到~/.ssh/id_ed25519。我建议用默认路径,后面配置省事。

执行之后,终端会问你要不要设置 passphrase(口令)。这个 passphrase 相当于给私钥再加一层 PIN 码,即使私钥文件被人拷走,没有 passphrase 也解不开。但代价是每次用私钥时都要输入一遍。我自己的习惯是设置一个 passphrase,然后把私钥交给 ssh-agent 保管,相当于只在开机后输入一次,后续都免了。这个平衡点很舒服。

也有不少人图省事直接回车留空。日常个人电脑上问题不大,但如果是公用电脑或者笔记本容易被拿走的情况,建议还是设置一下。

3.3 把私钥交给 ssh-agent 这次开机会话

ssh-agent 是一个后台程序,负责帮你保管已解锁的私钥。你只要在开机后执行一次ssh-add,之后这个会话里 Git 再使用私钥时就不会反复问你 passphrase 了。

macOS 和 Linux 上的操作:

eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519

Windows 上如果你用的是 Git Bash,命令和上面一样;如果用的是 PowerShell,需要先确认ssh-agent服务正在运行:

Start-Service ssh-agent ssh-add $HOME\.ssh\id_ed25519

这里最容易踩的坑是 Windows 的ssh-agent服务没有启动,导致ssh-add直接报错。你可以用Get-Service ssh-agent查看状态,如果是Disabled,需要以管理员身份运行 PowerShell,执行:

Set-Service -Name ssh-agent -StartupType Automatic Start-Service ssh-agent

3.4 复制公钥,粘贴到 GitHub 后台

公钥文件是~/.ssh/id_ed25519.pub,注意是带.pub后缀的那个,千万别把私钥内容贴出去。不同系统复制命令不一样:

macOS:

pbcopy < ~/.ssh/id_ed25519.pub

Linux:

xclip -sel clip < ~/.ssh/id_ed25519.pub # 如果没有 xclip,也可以直接 cat 后手动复制 cat ~/.ssh/id_ed25519.pub

Windows(PowerShell):

Get-Content $HOME\.ssh\id_ed25519.pub | Set-Clipboard

复制好后,登录 GitHub 网页端,进入Settings->SSH and GPG keys->New SSH key。Title 填一个你能认出来的名称,比如“Windows 办公机”或“MacBook Pro 2024”,Key 那个大框里粘贴公钥全文,最后点Add SSH key。

需要注意的细节是,有些编辑器会把一长串公钥自动换行,粘贴时尽量保证它是一整行,不要有多余的换行或空格。公钥的开头通常是ssh-ed25519 AAAAC3...,结尾是刚才-C参数里的注释邮箱,确认这三点基本不会错。

3.5 登记在 GitHub 上的到底是谁

这里再强调一遍:GitHub 后台只存放公钥,不存放私钥。你粘贴的内容来源于.pub文件,就算这把公钥被公开,别人也无法靠它冒充你。真正需要严格保护的是没有.pub后缀的私钥文件。经常有新手搞混,把id_ed25519贴到网页上,然后 SSH 连接各种失败,查了半天才发现贴错了文件,这个问题我后面排查章节还会提到。

4. 配置完成后必须先做的验证动作:避免“假成功”

配置完成之后不要急着git clone,先做一个连通性测试,确认你的私钥和公钥已经成功配对。执行:

ssh -T git@github.com

第一次连接时,终端会提示:

The authenticity of host 'github.com (IP地址)' can't be established. Are you sure you want to continue connecting (yes/no)?

这里的IP地址是 GitHub 服务器的 IP,不同时间可能不一样。输入yes回车即可,同时 GitHub 服务器的指纹会被记录进~/.ssh/known_hosts,之后不会再重复询问。

如果配置一切正常,你会看到:

Hi 你的用户名! You've successfully authenticated, but GitHub does not provide shell access.

看到Hi开头的那一行,说明认证已经通过。GitHub 它不允许 SSH 登录 shell,所以才说 “does not provide shell access”,这是正常现象,不是报错。

如果看到的是Permission denied (publickey),说明认证失败,常见的输出对应关系我整理成了表格:

提示信息含义处理思路
Hi username! ...认证成功什么都不用做
Permission denied (publickey)公钥/私钥配对失败检查 agent 是否加载私钥、公钥是否上传
Could not resolve hostname网络/DNS 问题检查 remote 地址是否写错
Port 22: Connection refused连接被拒绝检查防火墙、代理或尝试 443 端口

验证通过后,还需要把已经存在的仓库 remote 地址改成 SSH 形式。大多数人是 clone 的时候就选错了协议,仓库里存的 remote 还是https://开头。检查一下:

git remote -v

如果显示https://github.com/用户名/仓库名.git,执行:

git remote set-url origin git@github.com:用户名/仓库名.git

之后再git remote -v确认变过来了。以后git push就不需要任何凭据输入了。

还有一个值得养成的习惯是先检查 ssh-agent 里有没有加载私钥:

ssh-add -l

如果你看到The agent has no identities,说明私钥还没加进去,后面所有的 SSH 认证都会失败。但如果ssh-add -l能列出对应的密钥指纹,再配合ssh -T git@github.com成功,那整套链路就彻底通了。

5. 我踩过的那些坑:Permission denied 和 passphrase 引发的连锁反应

5.1 Permission denied 的完整排查链路

这个报错是配置 SSH Key 时出现频率最高的一个。我见过有人拿着这个报错折腾一下午,其实就是一个很小的地方漏了。我自己的排查顺序是这样的:

第一步,确认 GitHub 后台是否真的存了这把公钥。打开Settings->SSH and GPG keys,看看列表里有没有你刚加的那一把。有时候网页端显示“添加成功”,但浏览器插件或复制粘贴问题导致公钥内容被多加了空格,这种情况删掉重新添加即可。

第二步,确认本机 ssh-agent 里有没有私钥。执行ssh-add -l,如果输出为空,执行ssh-add ~/.ssh/id_ed25519重新加载。这里有个细节:每次重启电脑或者重开一个终端窗口,ssh-agent 可能不会自动加载私钥,需要重新ssh-add。

第三步,确认 remote 地址用的是git@github.com而不是用户名@github.com。SSH 协议连接 GitHub 时,用户名固定是git,如果你写成你的用户名@github.com,SSH 会拿这个用户名去尝试登录,同样会报 Permission denied。正确的格式是:

git@github.com:用户名/仓库名.git

第四步,检查~/.ssh/config文件。如果你之前配置过多主机连接,config 文件里可能有针对github.com的规则,把IdentityFile指到了另一个私钥文件上。这个问题的隐蔽性很高,因为表面上看你的配置都正确,但实际上 SSH 读取的是 config 文件指定的密钥。

5.2 passphrase 输错三次的后果与自救

ssh-agent 对 passphrase 的输入次数是有限制的。连续输错三次,SSH 会直接断开连接,并且不会明确告诉你“三次机会用完”,而是继续提示Permission denied (publickey)。很多人在这一步会陷入死循环:越想越急,越急越容易错,还以为是密钥本身出了问题。

如果你真的忘记了私钥 passphrase,那就不要挣扎了,私钥无法找回 passphrase,唯一的办法是重新生成一对新密钥。这也是为什么我建议把私钥文件放在一个稳定、安全的位置,并在第一次生成时就把 passphrase 记录到密码管理器里,避免长期不使用之后彻底遗忘。

自救的办法是在设置 passphrase 之后立刻执行一次:

ssh-add ~/.ssh/id_ed25519

输入正确 passphrase 后,私钥在这个会话内一直有效,期间反复 push 都不会再问。关键是养成“每次开机或新终端窗口先 ssh-add 一次”的习惯,就不会被 passphrase 卡住。

5.3 多个 key 文件同时存在的冲突

很多人电脑上不止一把 SSH 密钥:公司的 GitLab 一把,自己的 GitHub 一把,还有以前实验留下的 RSA 老密钥。当~/.ssh目录下塞了好几个 key 文件时,SSH 默认会依次尝试这些私钥,而 GitHub 那边看到的第一把私钥如果对不上后台公钥,就可能直接判定失败,不会继续尝试后面的。

解决方法是给~/.ssh/config文件写清楚每台主机用哪把私钥。最简配置长这样:

# 默认 GitHub 配置 Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519 # 公司的 GitLab Host gitlab.company.com HostName gitlab.company.com User git IdentityFile ~/.ssh/id_ed25519_company

这样 SSH 连接github.com时会精确指定第一把密钥,不会再乱试了。

5.4 Windows 上容易遇到的特殊情况

Windows 的坑比 macOS 和 Linux 多不少。最常见的是ssh-agent服务没有启动,前面已经讲过了。还有一个坑是某些 Git 安装包自带的 OpenSSH 和 Windows 系统自带的 OpenSSH 版本不一致,导致ssh-add之后密钥无法被 Git 正确读取。遇到这种情况,可以先在 Git Bash 里执行:

which ssh

如果路径指向 Git 安装目录下的usr/bin/ssh,和 PowerShell 里的ssh指向不同,那 Git 使用的 SSH 可能是旧版本。解决办法是在 Git 配置里把 SSH 客户端指向系统 OpenSSH:

git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"

改完之后重新ssh-add,再ssh -T git@github.com验证。Windows 下的clip命令在某些终端里也可能不生效,所以我前面直接用Get-Content | Set-Clipboard,在 PowerShell 里更可靠。

6. 多账号场景和密钥安全加固:比基础配置多走半步

6.1 一机多 GitHub 账号怎么玩

如果你有两个 GitHub 账号,比如一个个人号、一个工作号,千万别把同一个 key 同时加到两个账号上。GitHub 后台同一把公钥只允许关联一个账号,强行添加会报 “Key already in use”。正确做法是给每个账号生成独立的密钥对,并在~/.ssh/config里给第二个账号起一个别名:

Host github-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_work

然后 clone 第二个账号下的仓库时,remote 地址写成:

git@github-work:用户名/仓库名.git

推送时 SSH 会识别github-work这个别名,自动选用工作账号对应的私钥,两个账号互相不干扰。这个方案我用了很久,非常稳定。

6.2 密钥文件的权限和存放习惯

私钥文件的权限很重要。macOS 和 Linux 上如果权限过宽,SSH 直接拒绝使用这把私钥,并提示UNPROTECTED PRIVATE KEY FILE。安全的权限设置是:

chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519

公钥文件id_ed25519.pub的权限可以放宽一点,644没什么问题。如果你在 Windows 上用的是 OpenSSH for Windows,权限默认处理得比较严格,一般不需要手动改,但如果你把密钥文件放在了一个共享目录或有同步软件的目录里,最好改到只有当前用户能访问。

备份私钥也是一个值得考虑的习惯,但要注意备份方式。我的做法是加密压缩后放到离线 U 盘,而不是明文放在网盘或私有仓库里。私钥一旦明文泄露,就像把家门钥匙挂在墙上,别人随时可以复制。

6.3 定期检查后台 key 列表

配置完 SSH Key 不是一劳永逸的事。我每隔一段时间会登录 GitHub 后台,把SSH and GPG keys列表过一遍,看看有没有不认识的多余 key。尤其是当你更换电脑、卖掉旧设备时,一定要把旧设备的公钥删除。否则那台设备上的私钥一旦被其他人拿到,你的 GitHub 账号就等于门户大开。

查看本地密钥指纹的命令是:

ssh-keygen -l -f ~/.ssh/id_ed25519.pub

输出类似于256 SHA256:xxxx...,把这段指纹和 GitHub 后台显示的指纹对比一下,就能确认对应关系。这个方法也可以用来确认本地某个.pub文件是不是真的对应 GitHub 上某条 key。

另外,如果你在.ssh目录里有大量失效的 key 文件,建议定期清理。留一堆没用的私钥既占用位置,也增加了管理负担。我现在的习惯是每台电脑只保留当前环境需要的那两把 key,其余的用移存到离线备份里,不再放到工作目录中。

最后分享一点实际操作中的体会

换过两次电脑之后,我总结出了自己的一套标准流程:新机器上先ls -al ~/.ssh看有没有旧密钥,有旧的就直接复用,没有就ssh-keygen -t ed25519 -C "邮箱"生成,然后eval "$(ssh-agent -s)"、ssh-add ~/.ssh/id_ed25519,复制公钥到 GitHub 后台,最后ssh -T git@github.com验证。这个流程走一遍基本五分钟搞定,之后再也没被 Git 认证卡过。

最后再分享一个小技巧:如果你在配置过程中反复遇到同一个报错,不要连续尝试,停下来把当前执行过的命令和输出复制出来,逐行检查。大多数配置失败都是小细节——路径写错、复制了私钥、漏了 ssh-add、remote 地址写错成https://开头——把这些地方过一遍,比盲改 key 文件高效得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询