资讯详情

GitHub SSH Key密钥生成指南:从算法选型到权限排查

📅 2026/10/13 4:00:53 | 华诺云谱 👁 阅读
GitHub SSH Key密钥生成指南:从算法选型到权限排查
先说一个很多开发者都撞过的场景你在一台新电脑上装好Git习惯性用HTTPS地址往GitHub上推代码git push突然弹窗让你输入用户名密码输完一遍又一遍最后跳出来一个很模糊的错误提示显示认证失败。2021年之后GitHub官方已经不允许用账号密码通过Git协议推送代码了HTTPS方式只能改用Personal Access Token但不少人还是被推荐“去生成SSH Key”。这篇文章就把GitHub SSH Key密钥生成这件事从头到尾讲透包含密钥算法怎么选、命令参数怎么填、为什么一定要添加公钥、测试连接时常见的报错该怎么排查以及多账号环境下的进阶配置。无论你是刚接触GitHub的新手还是已经会用密钥但被各种报错折磨过这篇都值得花十分钟看一下。我尽量把每一步背后的原理和踩坑经验都写出来而不是只丢给你几条命令。1. 为什么你的推送会突然失败从密码认证失效说起1.1 一个诡异的现场clone正常、push一直报错我印象很深的是帮A同学排查这个问题。他电脑上clone仓库走HTTPS完全正常git clone能下载但一git push就卡在认证上终端提示输入用户名和密码。他反复确认密码没输错结果还是报错。后来我问了一句“你是不是还在用密码认证”他一脸茫然难道GitHub不是一直用账号密码认证吗这个现象就是历史上GitHub修改认证策略的直接影响。过去很长一段时间里HTTPS方式确实可以拿GitHub账号密码直接git push但后来官方收紧了这条路径不再支持密码作为Git协议的身份验证手段。HTTPS现在想用必须用Personal Access Token个人访问令牌代替密码或者改用SSH密钥。对大多数日常开发来说SSH密钥更省心配置一次之后就不用再反复输token。提示如果你在某台机器上还在用HTTPS clone线上仓库又不想改SSH可以在push时用https://你的tokengithub.com/用户名/仓库.git这样的地址但我不太推荐这个做法token很容易留在shell历史里安全上不划算。1.2 密钥认证和密码认证的本质区别密码认证的逻辑是“你既知道账号又知道密码我就让你进”这种方式最大的问题是密码会通过网络传输而且太容易被钓鱼。SSH密钥认证的逻辑完全不同它使用一对非对称密钥私钥留在本机公钥上传到GitHub。每次git push时本机用私钥对一段随机数据进行签名GitHub收到后用你之前上传的公钥去验证这个签名是否匹配。只要能通过就证明你确实持有这把私钥不需要传输密码。整个过程里私钥永远不出现在你的电脑上也不在网络里传输。这就像你家里换了一把智能锁门锁记录的是“这把钥匙的指纹信息”而不是“密码”。钥匙放在自己兜里开门时锁验证钥匙的合法身份而不是核对一句暗号。1.3 什么时候选SSH什么时候选HTTPS很多人问既然HTTPS也能用token为什么非要折腾SSH我的建议很直接临时下载公开仓库用HTTPS省事不用配置任何认证git clone一条命令就走。日常push代码用SSH配置一次长期省心不用每次输入token也不会遇到token过期的问题。某些内网环境只开放HTTPS端口也只能用HTTPS加token不过这种场景相对少见。SSH还有一个好处它可以避免你为了一个token去Web页面里反复复制粘贴。对日常高频push代码的开发者来说SSH的体验明显更顺滑。下面我们正式开始操作先别急着执行命令第一步的环境检查和算法选型很多人会忽略结果生成了一把不合适的密钥。2. 生成密钥前的准备和算法选型2.1 先检查自己的OpenSSH版本和已有密钥我不建议一上来就执行ssh-keygen。先花两分钟确认环境ssh -V如果你的输出里有OpenSSH 8.2、OpenSSH 9.x这类版本号说明系统自带的SSH工具链没问题。接着看看~/.ssh目录里是否已经存在密钥文件ls -la ~/.ssh常见的密钥文件名有id_ed25519、id_rsa等。如果这个目录里已经有一套密钥而你不知道它是干嘛的建议谨慎处理。强行覆盖旧密钥会让以前配置过的所有免密登录、GitHub账号、服务器登录全部失效。~/.ssh目录的默认权限也有讲究正常应该只有当前用户能读写不建议用共享目录存放密钥。Windows用户尤其注意不要把自己C:\Users\你的用户名\.ssh文件夹共享给其他账户。2.2 ed25519还是RSA一把钥匙的“材料”怎么选很多老教程还在让你生成rsa -b 4096这不能说错但已经不是最优解。现在的OpenSSH新版已经把ssh-rsa这种依赖SHA-1算法的签名方式默认关闭了很多新环境里你拿着RSA密钥也照样会被拒。ed25519是EdDSA签名算法的一种基于Curve25519椭圆曲线是目前SSH生态里非常推荐的密钥类型。它的优势非常明显对比维度ed25519RSA 4096公钥长度很短约68字符很长数百字符签名速度快相对慢安全性现代密码学强安全但依赖位数OpenSSH支持6.5之后都支持老算法新版默认禁用ssh-rsa签名适合场景全新环境、日常开发老旧系统、特殊兼容需求现在的GitHub完全支持ed25519密钥所以如果你没有特殊的兼容性需求新生成密钥直接选ed25519。什么情况需要RSA比如你在维护一台非常老旧的服务器系统里的OpenSSH版本还停留在6.5之前那才需要考虑单独生成一把RSA 4096的密钥。提示同一个GitHub账号可以同时添加多把公钥。日常电脑用ed25519老服务器单独用RSA完全互不干扰。2.3 ssh-keygen关键参数逐项拆解生成密钥的核心命令是ssh-keygen -t ed25519 -C 你的备注信息 -f ~/.ssh/id_ed25519 -a 100这里每个参数我都拆开解释一下-t ed25519指定密钥算法类型。如果特殊场景需要RSA就用-t rsa -b 4096。-C 备注信息这个叫comment通常建议写你的邮箱或者设备说明但它真的只是备注不会参与认证也不是必须和GitHub账号邮箱一致。它更像是你给这把钥匙贴的标签。-f ~/.ssh/id_ed25519指定私钥保存路径。很多人直接回车用默认路径这没问题但如果你同时管理多套密钥最好每次都用-f指定不冲突的文件名。-a 100设置KDF密钥派生函数的轮数。这个参数会影响密码短语的破解难度默认值是100建议保持默认或适当提高代价是解锁时稍微慢一点点。-C这个参数我见过不少误解总有同学以为必须填GitHub登录邮箱否则“不安全”。其实完全不是这样。你可以填成“A-Laptop”、“办公室台式机”这类人类可读的备注方便自己在多把公钥中区分。3. 生成密钥与配置过程完整操作演示3.1 生成密钥时终端里到底发生了什么现在正式执行生成命令ssh-keygen -t ed25519 -C A-Laptop -f ~/.ssh/id_ed25519 -a 100终端会问你保存路径如果-f已经指定了路径就直接回车跳过接下来是passphrase密码短语这一步很多人会直接留空。我的建议是不要留空设置一个你觉得顺手的passphrase。为什么因为私钥文件本身是静态的一旦被拷贝走对方只要拿到私钥文件就能冒充你登录。但如果你设置了passphrase私钥文件等于是加密存储的对方即使拿到文件没有passphrase也解不开。不过这里有个体验问题设置了passphrase以后每次SSH连接都可能要输一次。解决方式就是后面第三步要讲的ssh-agent让系统在一次登录会话里帮你记住“已解锁”的状态。执行过程大概会输出这些Generating public/private ed25519 key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/你/.ssh/id_ed25519 Your public key has been saved in /home/你/.ssh/id_ed25519.pub很多新手看到Your identification has been saved以为结束了其实这只是生成了两个文件带.pub后缀的是公钥可以公开不带后缀的是私钥一定要护好。3.2 查看公钥内容并完整复制查看公钥很简单cat ~/.ssh/id_ed25519.pub输出内容大致是ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKk... A-Laptop注意必须复制完整的一整行包括最开头的ssh-ed25519、中间一大串字符以及最后的备注。复制时建议用cat命令直接输出到终端再选中复制少了一个字符都会导致认证失败。这里要强调一个非常常见的错误有人把私钥文件id_ed25519的内容复制到了GitHub上。私钥的开头通常是-----BEGIN OPENSSH PRIVATE KEY-----如果看到这个开头那就说明复制错了赶紧停下私钥一旦暴露就要立刻吊销重来。3.3 把公钥添加到GitHub的完整步骤登录GitHub网页后按这个路径操作点右上角头像进入Settings。左侧菜单找到SSH and GPG keys。点击New SSH key按钮。在Title处填写一个设备标识比如A-Laptop这样以后你在这里看到的多把公钥能一眼分辨出哪一把对应哪台电脑。Key type保持默认的Authentication Key即可。它是用来做SSH身份认证的和下面那个Signing Key签名密钥不是一回事。把刚才复制的公钥粘贴到Key文本框里。注意这里粘贴的必须是.pub后缀文件里的内容。很多同学在这个环节会误以为“公钥不保密私钥才保密”结果为了图方便把私钥内容也贴出来测试这是绝对禁止的。3.4 ssh-agent让系统记住你的“已解锁状态”如果你设置了passphrase每次git push都要输一次真的很烦。ssh-agent就是为了解决这个问题存在的。它是一个后台服务负责在内存中保存已经解锁过的私钥后续SSH连接直接走它不再要求你重复输入passphrase。激活并添加私钥的命令eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519eval $(ssh-agent -s)这句代码的作用是启动agent并设置相关的环境变量。它会在后台运行一个ssh-agent进程并告诉你这个进程的PID。接着ssh-add会把指定的私钥加进去此时它会询问一次passphrase输入正确后私钥就驻留在agent里了。macOS用户我建议在添加时带一个钥匙串参数。在较新的macOS上可以这样ssh-add --apple-use-keychain ~/.ssh/id_ed25519这样一来不仅当前会话记住了以后重启电脑、重新登录终端它也直接从系统钥匙串里读取不需要一遍遍重新输入passphrase。Linux桌面环境则需要注意agent是否随系统自动启动如果每次开终端都要手动eval $(ssh-agent -s)建议把它写进shell配置文件的末尾Windows可以在“服务”里找到“OpenSSH Authentication Agent”把它设为“自动”并手动启动一次否则ssh-add会提示连不上agent。4. 测试连接与常见报错排查4.1 用ssh -T验证连接是否打通配置完一切后做一次连通性测试ssh -T gitgithub.com第一次连接时你的电脑会询问是否信任GitHub服务器的host key。这是因为SSH要验证你连的确实是GitHub避免中间人攻击。这里正常应该选择yes把服务器指纹写入~/.ssh/known_hosts。如果你看到指纹和官方公布的完全对不上先停下来确认是不是网络环境有问题。测试成功后你会看到类似下面的输出Hi A-username! Youve successfully authenticated, but GitHub does not provide shell access.这句话听着有点怪但它就是成功的意思。GitHub允许你用SSH做Git操作但不给你开一个真正的shell所以“does not provide shell access”完全正常不要被它吓到。如果你已经设置了passphrase而ssh-agent没有生效测试时会提示输入passphrase输入正确后同样能通过。如果觉得每次都问很烦回头检查一下agent状态和ssh-add -l的输出了没准。4.2 Permission denied (publickey)最经典的排查链路这个报错是SSH配置界最让人头疼的没有之一。好消息是它的排查链路非常固定按顺序走一般都能找到问题。先给一条万能调试命令ssh -vT gitgithub.com-v参数会打印详细的调试日志。看到报错后按下面顺序排查确认本地私钥存在且被agent加载ssh-add -l输出里如果能看到你的密钥指纹说明agent里有私钥如果提示The agent has no identities说明agent没加载先执行ssh-add ~/.ssh/id_ed25519。查看调试日志里是否出现“Offering public key”日志里如果显示你提供了公钥但服务器仍然拒绝问题很可能出在GitHub那边比如公钥没添加、被删除、粘贴时少了字符。确认GitHub网页上公钥粘贴正确登录GitHub重新打开SSH keys页面检查这把公钥是否在列表里内容是否和本地.pub完全一致。很多人习惯复制过之后再手改结果多了一个空格或换行直接导致验证失败。检查~/.ssh/config里是否写错IdentityFile如果你设置了多主机配置ssh -vT gitgithub.com会读取~/.ssh/config中匹配github.com的那一段并按照IdentityFile指定的路径找私钥。一旦路径写错也会报Permission denied。排查系统时间极少见但确实存在系统时间和真实时间差太多会导致签名校验失败。检查一下系统时间是否正常。这条链路99%能找出问题。最让人哭笑不得的还有两种一种是复制私钥内容当公钥上传另一种是上传公钥时把末尾的换行符带进去了虽然网页上看不出来但实际校验时就是不过。遇到这种直接删掉重新粘贴一次最稳妥。4.3 权限问题WARNING: UNPROTECTED PRIVATE KEY FILE在Linux和macOS上如果私钥文件的权限过宽SSH会直接拒绝使用并警告WARNING: UNPROTECTED PRIVATE KEY FILE!这个设计是为了防止其他用户读取你的私钥。解决办法很简单把权限收窄chmod 600 ~/.ssh/id_ed25519 chmod 700 ~/.ssh一般建议普通文件用600目录用700。这个权限意味着只有你本人能读写或进入目录其他人一概不允许。Windows的OpenSSH也会有类似的路径权限问题主要出现在你把.ssh目录放在非默认位置或共享目录时。解决办法是在%USERPROFILE%\.ssh目录上确认只有当前用户有完全控制权限其他用户的权限项全部移除。提示如果你把私钥放在U盘或者云盘里当备份注意这属于非常敏感的行为建议至少使用加密压缩包。公钥随便放私钥的每一次复制都要谨慎。5. 多账号、多设备与密钥生命周期管理5.1 一台电脑管理两个GitHub账号很多人实际有多个GitHub账号比如一个工作号一个个人号。如果把两套密钥都命名为默认的id_ed25519后生成的会覆盖之前的这就是一个巨大的坑。正确做法是每个账号一套独立密钥文件。在生成阶段就给它们起不同名字ssh-keygen -t ed25519 -C work -f ~/.ssh/id_ed25519_work ssh-keygen -t ed25519 -C personal -f ~/.ssh/id_ed25519_personal然后编辑~/.ssh/config写入配置Host github-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_work IdentitiesOnly yes Host github-personal HostName github.com User git IdentityFile ~/.ssh/id_ed25519_personal IdentitiesOnly yes这里有一个极高的价值点IdentitiesOnly yes。如果没有这一行SSH会把agent里所有已加载的密钥依次拿去尝试一旦默认的那把个人密钥被agent加载它会优先被提交到GitHub服务器一看没有这把公钥就会拒绝。加上这行SSH只会使用你指定的IdentityFile不会“顺手”拿别的密钥去试。测试时用不同的Host别名ssh -T gitgithub-work ssh -T gitgithub-personalclone仓库时也把地址里的github.com换成别名比如git clone gitgithub-work:用户名/仓库.git5.2 多设备公钥是共享的私钥是私有的换了新电脑后我见过有人直接问“怎么把私钥迁移过去”这操作不是不行只是风险更高。更推荐的做法是每台设备分别生成一套新的密钥然后把各自的公钥都添加到同一个GitHub账号下。这样做的好处很多。每台设备独立私钥即使其中一台电脑丢了你只需要在GitHub上删掉对应的那一把公钥其他设备完全不受影响。如果所有设备共用同一把私钥一旦有一台机器被入侵必须所有设备全部重新生成工作量翻倍。在GitHub的SSH keys列表里你添加的每把公钥都用一个Title来区分比如A-Laptop、A-Desktop、A-Server。清理时先确认Title对应的设备再点Delete非常直观。建议养成每次新添加公钥都把Title写清楚的习惯否则几个月后你会面对一堆MacBook、Laptop这种毫无区分度的名字想删又不敢删。5.3 更换密钥和撤销密钥的安全操作清单当发生这些情况时你需要马上处理旧电脑淘汰或丢失某个使用记录不明的密钥疑似泄露离职切换账号长期没用的公钥想清理。撤销的流程是先在GitHub的SSH keys页面删除对应公钥然后在本机删除或回收对应私钥文件。如果怀疑私钥泄露删除后最好生成一把新密钥并把新公钥加回去。这个顺序不能颠倒先撤销再生成避免出现“新密钥还没生效旧密钥又不管用”的尴尬。另外如果你之前用SSH密钥做过Git提交签名撤销密钥后那些签名还在历史记录里只是验证状态会变成无法验证。签名密钥和认证密钥建议分开管理认证密钥用于SSH连接签名密钥用于git commit -S签名。在GitHub设置里这两类密钥也是分开添加的。6. 最后再分享几个关于密钥的小经验我自己折腾过很多次密钥问题之后最大的体会是密钥生成本身不是难点难的是“环境干净”和“配置清晰”。每次在全新环境配置前我会先把ssh -V、ls ~/.ssh、ssh-add -l这三条命令跑一遍搞清楚现状再动手。设置passphrase虽然多了一步输入但配合ssh-agent之后体验并不差而安全收益是实打实的。如果你嫌麻烦至少要保证私钥权限正确并且不要把私钥传去任何在线聊天工具、云笔记或公开仓库。另一个很实用的习惯是公钥文件里那个-C注释尽量写成“设备名用途”比如A-Linux-Server、A-MacBook-Pro。这样你在GitHub的SSK keys列表里能快速识别出每一把公钥对应的设备。我见过有人把所有密钥都注释成自己的邮箱结果密钥一多连自己都分不清哪台机器是哪把排查问题的时候要多花不少时间。最后如果你想让git提交历史里出现“Verified”标识可以进一步研究用同一把SSH密钥配置commit签名。但那是另一个话题先把认证密钥这关彻底搞明白再考虑签名密钥会顺手得多。如果这篇文章帮你少踩了一个坑可以把它转发给身边还在被Permission denied困扰的朋友。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑