资讯动态

Git SSH Key配置详解:从密钥生成到免密推送

发布时间:2026/9/18 6:04:01 来源:尧图企业网站定制
1. 项目核心思路为什么Git非要配SSH Key先聊聊我自己的经历。第一次用Git往GitHub上推代码的时候用的是HTTPS方式每次推送都要输一遍用户名和密码烦得不行。后来有一次在公司电脑上配好了仓库地址回家想再推一次结果GitHub改了密码策略我连着试了三次密码都报错整个人都快炸了。后来老老实实花十分钟把SSH Key配好世界清净了——从那天起我再也没为推送认证烦心过。很多人会问GitHub明明也支持HTTPS克隆和推送为什么还要折腾SSH Key这里面的核心区别在于认证机制。HTTPS用的是“用户名密码”或“Personal Access Token”的每次请求认证而SSH Key用的是“非对称加密”的密钥对认证。说白了HTTPS是每次进门都要掏身份证SSH是配好之后进门直接刷脸。SSH Key的原理可以这样理解它包含一把私钥Private Key和一把公钥Public Key。私钥留在你本地电脑上绝对不能给别人看它是你身份的“唯一凭证”公钥可以公开你把它配置到GitHub账号里相当于告诉GitHub“持有这把私钥的人是我本人”。当你用SSH协议连接GitHub时GitHub会发一个随机挑战你的本地Git用私钥对它签名GitHub再用公钥验证签名。数学上保证了只有持有对应私钥的人才能通过验证。在继续往下之前我要先做一个必要的安全说明公钥和私钥在这里指的完全是Git SSH配置场景下的本地密钥文件与任何网络访问工具、代理服务没有任何关系。下文所有操作都只围绕“本地生成密钥、配置到GitHub账号、验证连接”这条标准技术路线展开。这套方案适合谁如果你是刚开始用Git的初学者每次clone和push都要输密码或者已经遇到Permission denied (publickey)报错那这篇文章就是给你准备的。就算你用的是Windows、macOS还是Linux核心思路完全一样差别只在几个系统命令上。我会用Windows作为主要演示环境因为Windows上踩坑最多其他系统我会顺带提一句差异。2. 前置准备装好Git并确认版本2.1 安装Git的两种方式我见过不少人直接一路“Next”把Git装完就以为万事大吉结果后面配SSH Key的时候到处找不到ssh-keygen命令。这里给大家两个安装选择。第一种方式是直接从Git官网下载安装包。下载后双击运行安装过程中有几个关键选项需要注意“Select Components”页面建议勾选“Git Bash Here”和“Git GUI Here”这样右键菜单里会多出两个入口后面操作会方便很多。“Choosing the default editor used by Git”可以保持默认的Vim如果想用VS Code也可以在这儿选。“Adjusting your PATH environment”这一步一定要选第二项“Git from the command line and also from 3rd-party software”否则后面在PowerShell或CMD里敲git命令会提示找不到。“Choosing the SSH executable”保持默认的“OpenSSH”即可这是Windows自带的SSH组件不用额外安装。第二种方式是Windows下用winget install --id Git.Git直接装适合习惯命令行操作的同学。装完以后重启一次终端让PATH环境变量生效。2.2 验证安装结果打开Git Bash或PowerShell输入以下命令git --version ssh -V正常情况下会看到类似这样的输出git version 2.42.0.windows.2 OpenSSH_9.5p1, OpenSSL 3.0.12如果你git --version有输出但ssh -V报错说明系统里没有自带OpenSSH客户端。这种情况在Windows 10以下系统比较常见Windows 10及以上都内置了OpenSSH客户端一般不会出现这种问题。真遇到了可以在系统的“可选功能”里把“OpenSSH客户端”勾上安装或者装一个Git for Windows后重新打开Git Bash因为Git for Windows里自带了SSH工具。2.3 设置Git用户名和邮箱重要但容易被跳过这一步很多人会跳过但它直接影响你后面commit记录里的作者信息。如果你用的是本地仓库方式提交记录里会显示一个“unknown”的作者等推到GitHub上就会变成一堆匿名提交。打开Git Bash执行git config --global user.name 你的GitHub用户名 git config --global user.email 你注册GitHub的邮箱这两条命令把用户名和邮箱写进了全局配置也就是~/.gitconfig文件。需要注意的是这里的邮箱建议和GitHub注册邮箱保持一致这样提交记录才能和你的GitHub账号正确关联。用git config --global --list可以查看当前配置是否生效。3. 生成SSH Key密钥对到底怎么来的3.1 ssh-keygen命令的完整参数解析打开Git Bash执行以下命令ssh-keygen -t ed25519 -C 你的GitHub注册邮箱这里我用了ed25519算法而不是传统的rsa原因是Ed25519密钥更短、生成更快、安全性更高。如果用的是老版本Git或OpenSSH也可能不支持Ed25519那可以用ssh-keygen -t rsa -b 4096 -C 你的GitHub注册邮箱-t参数指定密钥类型-b指定密钥长度RSA算法下建议4096位-C是注释用来标记这把密钥的归属。注释内容可以是任意字符串只是给人看的不影响实际认证效果。执行命令后系统会提示Generating public/private ed25519 key pair. Enter file in which to save the key (/c/Users/你的用户名/.ssh/id_ed25519):这里直接按回车即可使用默认路径。如果想给密钥起个不同的名字比如公司电脑和个人电脑区分开可以在这里输入/c/Users/你的用户名/.ssh/id_ed25519_company。但要注意如果你想使用非默认名称后续需要在~/.ssh/config文件里配置才能让Git自动识别否则还是老老实实用默认名最省事。接下来会有两个交互式问题第一个是设置私钥的密码passphrase第二个是重复输入一次确认。Enter passphrase (empty for no passphrase): Enter same passphrase again:这里的passphrase相当于给私钥再加一层保险。如果设了密码每次用SSH连接GitHub时都要输入一次如果不设私钥文件本身一旦泄露对方可以直接使用。我的建议是个人电脑可以留空公司电脑或公用电脑建议设置。后文“常见问题”部分我会详细讲怎么修改或取消passphrase。3.2 生成后的文件结构生成完成后~/.ssh/目录下会出现两个文件id_ed25519私钥文件权限必须严格控制任何人拿到它就能冒充你。id_ed25519.pub公钥文件内容可以公开这就是要配置到GitHub上的东西。这里有个细节值得注意公钥文件的内容是一行以ssh-ed25519 AAAA...开头、以你之前设置的邮箱结尾的字符串中间的AAAA...是Base64编码的公钥数据。整个公钥内容是公开的就算被别人看到也没有风险——这正是非对称加密的设计精髓公钥用于加密和验证私钥用于解密和签名。对于rsa算法生成的公钥开头则是ssh-rsa AAAA...。如果看到公钥内容长得不像是这两种开头先检查一下是不是文件读错了。4. 把公钥配置到GitHub账号4.1 复制公钥内容公钥文件是一个纯文本内容格式是一整行。我们只需要这一行内容不需要换行也不要有其他多余字符。Windows下用Git Bash可以用以下命令直接复制clip ~/.ssh/id_ed25519.pubmacOS下用pbcopy ~/.ssh/id_ed25519.pubLinux下用cat ~/.ssh/id_ed25519.pub然后手动选中复制。复制之前可以先用cat ~/.ssh/id_ed25519.pub查看一下公钥内容确认末尾有你的邮箱注释。这里有个小坑Windows下如果用记事本打开.pub文件再全选复制有可能把换行符也复制进去导致粘贴的时候公钥串断成两行GitHub会提示格式不对。最稳妥的方式就是上面给的复制命令直接复制到剪贴板不会有换行符问题。4.2 GitHub上的操作路径登录GitHub后按以下路径操作点击右上角头像选择“Settings”。左侧菜单拉到最下面找到“SSH and GPG keys”。点击右上角绿色按钮“New SSH key”。“Title”输入一个便于识别的名字比如“Work-PC”或“Home-Laptop”这个只是备注作用。“Key type”选择“Authentication Key”这是SSH认证专用的类型。如果要配置签名密钥才选“Signing Key”但那种用法更多是配合GPG做提交签名不在本次讨论范围内。“Key”粘贴刚刚复制的公钥内容。点击“Add SSH key”会要求输入一次GitHub登录密码或完成两步验证确认。完成以后Key列表里会出现一条记录前面会显示公钥指纹Fingerprint。这里显示的SHA256:后面跟一串字符就是SSH公钥的指纹用来唯一标识这把密钥。4.3 一个账号配多台电脑的情况你可能在家里和公司各有一台电脑两台都往同一个GitHub账号推代码。这种场景不需要删掉旧的重新配直接在同一个账号下添加多个公钥即可。GitHub允许一个账号绑定多个公钥每台电脑对应一个不同的密钥对互不冲突。我给每台电脑的公钥都取了不同的Title比如“thinkpad-x1”和“desktop-pc”方便以后排查问题。反过来如果你有多台电脑共用同一套公钥文件也不是不行但一旦私钥泄露所有电脑都要重新生成。所以更推荐每台电脑各自生成独立密钥把对应的公钥分别加到GitHub账号下。5. 测试连接验证SSH Key是否配置成功5.1 标准的测试命令配置完成后在Git Bash里输入ssh -T gitgithub.com第一次连接时会有一个提示The authenticity of host github.com (140.82.121.4) cant be established. ED25519 key fingerprint is SHA256:DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])?这是在询问你是否信任GitHub服务器的指纹输入yes后回车即可。系统会把GitHub的指纹记录到~/.ssh/known_hosts文件里以后就不会再问。验证成功的输出是这样的Hi 你的GitHub用户名! Youve successfully authenticated, but GitHub does not provide shell access.看到这行就说明认证通过了。注意最后那句“does not provide shell access”不是报错而是GitHub的SSH服务只做Git操作不提供交互式终端的意思。如果认证失败通常会看到gitgithub.com: Permission denied (publickey).这个问题我们下一章重点排查。5.2 如何验证密钥指纹是否正确在确认GitHub服务器指纹时可以参照GitHub官方文档给出的指纹列表。我自己习惯的验证方式是在GitHub网页端登录后进入任意一个仓库页面浏览器地址栏旁边那个锁形图标点击一下查看连接详情确认证书和指纹信息是否一致。不过对于绝大多数人来说第一次连接时直接输入yes也够了因为SSH的指纹校验机制本身就具备防中间人攻击的能力只要你在没被劫持的网络环境下操作默认信任是安全的。5.3 SSH连接与HTTPS连接的实际对比测试通过后可以实际感受一下差异。在GitHub仓库页面选择“SSH”方式复制地址之后克隆速度会比以前用HTTPS时明显更快而且后续的push和pull操作全程不用输密码。如果你的项目是自动部署到服务器上的比如用GitHub Actions或Jenkins那SSH Key的意义就更大了——CI/CD流程里没有交互式输入密码的环境只能用SSH Key或Token做免密认证。6. 常见问题与排查技巧实录6.1 Permission denied (publickey) 报错的第一梯队排查这是最经典、出现频率最高的报错我从Permission denied (publickey)入手说说排查的优先级第一确认公钥是不是真的加到GitHub上了。去GitHub的“SSH and GPG keys”页面看一眼确认公钥存在、内容没有多余换行。第二确认本地用的是不是默认密钥文件。如果你之前用ssh-keygen时改了文件名比如生成了id_ed25519_company但Git默认会去找id_ed25519这时候当然认证失败。解决办法是写~/.ssh/config文件把特定Host和密钥文件关联起来或者重新生成一把默认命名的密钥。第三用ssh -vT gitgithub.com这个详细模式来查看连接日志。注意-v参数会让SSH输出详细的调试信息里面会明确提示尝试使用哪些密钥文件、服务器是否接受、最后失败在哪一步。如果输出里有一行Offering public key: /c/Users/xxx/.ssh/id_ed25519.pub且后面显示Authentications that can continue: publickey说明密钥质量没问题问题出在服务端的公钥匹配上。一个有代表性的排查输出大致长这样OpenSSH_9.5p1, OpenSSL 3.0.12 debug1: Reading configuration data /c/Users/xxx/.ssh/config debug1: Connecting to github.com [140.82.121.4] port 22. debug1: Connection established. debug1: identity file /c/Users/xxx/.ssh/id_ed25519 type 0 debug1: Offering public key: /c/Users/xxx/.ssh/id_ed25519.pub debug1: Server accepts key: /c/Users/xxx/.ssh/id_ed25519.pub debug1: Authentications that can continue: publickey如果走到了“Server accepts key”却依然失败那大概率是GitHub账号上的公钥内容和你本地公钥文件不一致重新粘贴一次即可。6.2 Host key verification failed 的处理方式这个报错出现的原因是known_hosts文件里记录了某个IP对应的指纹但当前连的服务器指纹变了或者GitHub的IP变了导致记录到了另一个条目。处理方法分成两种第一种如果确定连接的是GitHub官方地址可以直接删除~/.ssh/known_hosts文件里所有GitHub相关条目然后重新执行ssh -T gitgithub.com重新接受新的指纹。第二种用命令直接删除指定主机名的记录ssh-keygen -R github.com这个命令会把known_hosts中所有关于github.com的记录都清掉。清完以后重新连接即可。这里要特别提醒一下known_hosts和authorized_keys是两个完全不同的文件。known_hosts存储的是你本地信任的服务器指纹authorized_keys是服务器端存储的允许登录的客户端公钥。在GitHub的场景下你不需要关心authorized_keys因为GitHub的服务端会替你做鉴权。6.3 私钥密码忘记了怎么办如果你设置了passphrase但忘了按理说私钥无法直接解密但有一个取巧的办法重新生成一把新密钥然后去GitHub后台把旧公钥删掉、加新公钥。这种做法等于把旧的密钥对作废用新的替代。生成的步骤和第一次完全一样唯一不同的是这次的公钥指纹变了。如果你没设置passphrase但想加上可以用ssh-keygen -p -f ~/.ssh/id_ed25519这会提示你先输入旧密码如果否的话直接回车然后设置新密码。整个过程不会改变公钥文件的内容因为公钥是从私钥中推导出来的私钥内容未变则公钥也不变所以GitHub上的公钥记录不用动。6.4 多账号场景下的SSH配置很多人会遇到这样的情况一个GitHub账号用于工作一个用于个人开源项目但本地都是同样的默认密钥文件就会出现“A账号的公钥覆盖了B账号的授权”的问题。解决思路是给不同账号使用不同的密钥文件并通过~/.ssh/config文件做路由。比如Host github-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_work Host github-personal HostName github.com User git IdentityFile ~/.ssh/id_ed25519_personal配置完后工作仓库用gitgithub-work:组织名/仓库名.git这种方式来clone或添加远程地址个人仓库用gitgithub-personal:用户名/仓库名.git。这样两个账号互不干扰本地git仓库也能精确区分用哪个密钥。这个方案在Windows和macOS上都是一样的只是配置文件路径不同。Windows下是C:\Users\xxx\.ssh\configmacOS和Linux下是~/.ssh/config。6.5 常见问题速查表为了便于快速定位问题我把常见现象和处理方法整理成了下面这张表这个表里说的都是本地密钥文件在SSH标准配置流程中的常见问题不涉及任何网络层面的工具或服务。报错/现象原因处理方法Permission denied (publickey)公钥未配置到账号或本地密钥非默认路径检查GitHub后台公钥检查~/.ssh下文件命名Host key verification failedknown_hosts指纹过期或变了ssh-keygen -R github.com后重连Bad owner or permissions私钥文件权限过宽Windows下在文件属性中移除继承权限macOS/Linux用chmod 600Could not open a connection to your authentication agentssh-agent没有运行或没有添加密钥先执行eval $(ssh-agent -s)再ssh-add ~/.ssh/id_ed25519Connection refused / Operation timed out网络问题或GitHub访问异常等一会儿重试或确认本地网络状态正常Enter passphrase for key 反复出现私钥设了passphrase或ssh-agent没记住输入正确密码或配置ssh-add加入agent6.6 私钥文件权限问题的深度解释Windows上打开~/.ssh目录右键私钥文件选择“属性” - “安全” - “高级”如果看到“来自父目录的继承权限”说明权限太宽了。SSH客户端会拒绝使用权限过宽的私钥。处理方法是点击“禁用继承”然后只保留当前用户的完全控制权限其他用户全部删除。macOS和Linux下标准操作是chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pubchmod 600的意思是只有文件所有者可以读写其他人没有任何权限。对于包含私钥的文件来说这是最安全的选择。而公钥文件因为要给别人看644权限就够了。6.7 ssh-agent的作用和配置ssh-agent是一个运行在后台的守护进程主要作用是缓存私钥的明文密码。如果你设置了passphrase每次SSH连接都要输入密码会比较烦。配置好ssh-agent后只需在系统启动时输入一次密码之后所有SSH连接都会自动使用缓存中的密钥。Windows下我在Git Bash里执行eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519macOS下系统默认会自动启动ssh-agent只要执行ssh-add ~/.ssh/id_ed25519即可。如果你用的是macOS的钥匙串访问加-K参数可以让私钥密码保存到钥匙串中永久免输。Linux桌面环境下的设置方法稍有不同取决于你是否用桌面管理器不过思路还是一样的。这里有个细节ssh-agent里添加密钥的多少会影响SSH连接的认证方式。如果添加了多个密钥SSH客户端会按顺序尝试每一个密钥直到服务端接受了某一个。如果你只添加了一个密钥连接速度会更快因为不需要反复尝试。7. 从SSH Key到日常开发流程的落地衔接配好SSH Key以后整个Git操作的体验会有很大提升。这里分享几个我实际用下来的经验和操作习惯。7.1 克隆仓库时优先选择SSH地址在GitHub仓库页面点击绿色“Code”按钮切换为“SSH”标签复制地址然后git clone gitgithub.com:用户名/仓库名.git之后在这个仓库里的所有push、pull操作都不会再要求输密码。如果你之前已经用HTTPS方式克隆了仓库可以这样改远程地址git remote set-url origin gitgithub.com:用户名/仓库名.git改完之后用git remote -v确认一下远程地址是否已更新。这个操作不会影响本地分支和提交历史只是改了以后推送时走的协议。7.2 配置提交签名进阶选项SSH Key除了用于认证之外还可以用于提交签名Commit Signing。GitHub支持用SSH密钥为commit做GPG风格的签名这样在提交记录里会显示“Verified”的蓝色标记。操作方式是先在GitHub的“SSH and GPG keys”页面添加一把类型为“Signing Key”的密钥然后本地执行git config --global gpg.format ssh git config --global user.signingkey ~/.ssh/id_ed25519.pub git config --global commit.gpgsign true之后每次commit会自动签名。这个配置不是所有人必需的但对开源项目维护者来说验证过的提交记录会更受人信任。7.3 维护多个仓库时避免踩坑公司和个人项目同时存在时一个容易忽略的问题是不同项目可能用了不同的Git配置。比如公司项目里设置了独立的用户名和邮箱而全局配置是个人信息。这种情况建议在项目目录下用git config user.name和git config user.email单独设置覆盖全局配置。多账号SSH Key的处理我之前已经讲过这里再补充一个细节如果你在~/.ssh/config里给不同Host配置了不同的IdentityFile那ssh -T gitgithub-work和ssh -T gitgithub-personal可以分别测试两个账号的连接情况。建议每配好一个账号就测一次不要等到推送时才排查。7.4 密钥备份与迁移的正确姿势很多人会问换电脑以后之前的密钥能不能直接用可以但要注意安全。可以复制~/.ssh整个目录到新电脑但传输过程必须用加密方式比如U盘加密码或加密压缩包。千万不要把私钥发到聊天工具里。我个人更推荐的做法是新电脑上重新生成一把新密钥把新公钥加到GitHub后台旧电脑上的公钥可以删掉。这样即便旧电脑丢失也只是作废一把密钥的问题不需要担心长期隐患。7.5 自动部署场景下的SSH Key用法如果你在服务器上部署代码比如用GitHub Actions或自己的CI/CD工具那些流程里配置SSH Key的方式略有不同。GitHub Actions可以在仓库的Settings - Secrets里添加SSH_PRIVATE_KEY这样的环境变量然后由流水线把它写入CI环境。由于CI环境是临时的每次构建都会重新生成一个全新的~/.ssh目录所以把私钥作为Secret传入是安全的标准做法。这里要特别提醒的是任何不用的SSH Key都应该及时从GitHub后台删除。如果某天你的个人电脑丢了不要慌登录GitHub把对应的公钥删掉然后重新生成新密钥补上就行。养成“密钥生命周期管理”的习惯是每个Git重度用户应该有的基本意识。8. 这次配置过程中我踩过的坑最后分享几个我实际踩过的坑有些是技术问题有些纯粹是操作习惯问题但都挺有价值。第一个坑是Windows下clip命令复制公钥后如果公钥里包含特殊字符粘贴到GitHub的文本框会被自动加上一个尾巴。原因是Windows的剪贴板可能携带了额外的格式信息。后来我习惯在粘贴后在key字段末尾敲一个回车确保输入框里没有残留空格。第二个坑是公司电脑上安装过某种安全软件后会把~/.ssh目录的权限改掉导致原本能用的SSH Key突然失效。排查了很久才发现是安全软件对“个人目录下的隐藏文件夹”做的保护策略。这种问题不容易定位建议先看ssh -vT输出确认是不是权限问题。第三个坑是自定义~/.ssh/config文件的时候缩进和空格写错了。比如HostName前面多了一个空格或者IdentityFile路径写错SSH会静默忽略这一条配置然后按默认行为尝试密钥文件。这种问题很隐蔽排查半天都找不到原因。后来我习惯了每改完config文件先执行ssh -T gitgithub.com做验证能连上再继续下一步。配置SSH Key这件事本身不难难的是理解每一步背后的意义。公钥和私钥的关系、known_hosts和authorized_keys的区别、passphrase的作用、ssh-agent的缓存机制——这些概念一旦理解了遇到再奇怪的报错都不会慌。根据我个人经验最值得花时间的反而是把~/.ssh目录的各种文件弄明白因为以后你会上很多台服务器、配很多个Git仓库这些知识会反复被用到。最后一个实用的小技巧如果某一天你的ssh -T gitgithub.com突然要你输入密码八成是私钥文件权限被改了或者ssh-agent里没有加载密钥。先用ssh -vT看详细日志别急着删密钥重新生成很多问题都是配置问题而不是密钥本身的问题。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价