
1. 为什么要在 Mac 上给 GitHub 配置 SSH keys先说个我经常被问到的问题明明 HTTPS 方式也能 push 代码为什么还要折腾 SSH keys这得从 GitHub 的两种认证方式说起。HTTPS 方式每次推送都需要输入用户名和密码虽然在 Mac 上钥匙串Keychain能帮你记住密码但遇到公司电脑、多台设备、频繁切换账号的场景HTTPS 的体验就很痛苦了——经常出现密码过期、凭据冲突、甚至莫名弹窗。SSH keys 的本质是一对非对称加密密钥私钥留在本机公钥放到 GitHub 账号里。推送代码时GitHub 用公钥验证你的身份本机用私钥完成签名整个过程不需要输入任何密码纯靠密钥文件完成认证。这个方案适合谁如果你需要日常频繁 clone、push、pull GitHub 仓库在多台 Mac 上管理同一个 GitHub 账号同时管理多个 GitHub 账号比如个人号 公司号在 CI/CD 环境里做自动化部署需要免密访问私有仓库那我强烈建议你花十分钟把 SSH keys 配好后面能省下大量重复输入密码的时间。有一点需要提前说明SSH 配置属于网络层面的安全设置只涉及本地密钥文件和 GitHub 账号的对应关系。实际操作时请确保你的网络环境能正常访问 GitHub 网页端比如能打开 github.com 的仓库页面这是后续所有步骤的基础前提。如果连网页都打不开先解决网络连通性问题再说。顺便把几个基本概念交代清楚后面实操时你会频繁遇到它们术语含义在配置中的作用SSHSecure Shell安全外壳协议Git 通过它建立与 GitHub 服务器的加密通道私钥保存在本机的密钥文件用于签名认证绝不能泄露或上传公钥上传到 GitHub 的密钥文件放在服务器端用于验证本机身份ssh-agentSSH 密钥管理服务负责保管私钥免去重复输入密码fingerprint密钥指纹一串用于识别密钥的短字符串安全提示时会用到先理解了这些名词后面操作起来就不会一头雾水。2. 动手前的准备检查已有密钥与安装环境2.1 检查是否已经存在 SSH 密钥很多 Mac 用户其实以前生成过密钥但时隔太久自己都忘了。直接生成新密钥会覆盖旧密钥导致原有配置失效所以第一步一定是检查。打开终端Terminal输入以下命令ls -la ~/.ssh如果显示No such file or directory说明从来没配置过 SSH 密钥可以放心地进入下一节生成新密钥。如果目录存在里面会有类似下面的文件id_rsa和id_rsa.pub老式 RSA 算法的密钥对id_ed25519和id_ed25519.pub新版 Ed25519 算法的密钥对configSSH 配置文件多账号场景下会用到看到这些文件先别急着删除。我的建议是确认一下这套密钥之前是否用过ssh -T gitgithub.com如果返回Hi 你的用户名! Youve successfully authenticated, but GitHub does not provide shell access.说明这套密钥已经绑定过 GitHub 账号你可以直接用它不需要重新生成。如果返回Permission denied (publickey)说明密钥存在但没在 GitHub 上配置过对应的公钥可选用现有密钥追加到 GitHub也可以重新生成一套新的。2.2 确认 Git 版本与终端环境Git 是配置 SSH 的前置依赖先确认它装好了git --version如果提示command not found有两个安装途径。一是安装 Xcode Command Line Toolsxcode-select --install系统会弹出安装窗口点击确认后等待几分钟即可。装好后再执行git --version验证。二是在官网下载 Git 安装包或者用 Homebrew 安装看个人习惯。安装过程本身不复杂但 Xcode Command Line Tools 这种方式最省事因为它是 Apple 官方维护的后续很多开发工具都会依赖它。2.3 终端工具的选择与准备Mac 自带终端 Spotlight 搜索 Terminal 就能打开功能完全够用。如果你想要更好的体验iTerm2 也是个不错的选择支持分屏、多标签、自定义快捷键我个人平时用 iTerm2 更多。不过本文所有命令在两个终端中都通用不影响操作。有一点要注意后续所有命令都必须在终端中执行。如果你习惯用 VS Code 的集成终端也可以但要确保当前用户是正常的 macOS 登录用户而不是 root。直接用 root 生成密钥会带来权限问题后面 git 命令会报错说无法读取密钥文件。3. SSH 密钥生成从命令到原理3.1 ssh-keygen 参数选择详解生成密钥的标准命令是ssh-keygen -t ed25519 -C 你的邮箱example.com -f ~/.ssh/id_ed25519拆开来看每个参数的含义-t ed25519指定密钥算法。Ed25519 是目前推荐使用的算法密钥短、安全性高、生成速度快。相比之下老式 RSA 算法密钥长度动辄 4096 位文件大且生成慢。除非你要连接的是不支持 Ed25519 的远古服务器否则优先选 Ed25519。-C 你的邮箱标注注释信息方便识别密钥来源。这里填的是 GitHub 账号绑定的邮箱不是登录密码可以放心填写。-f ~/.ssh/id_ed25519指定密钥文件保存路径。-f参数会在后面弹交互式问题时自动填入路径省去手动输入的麻烦。执行命令后终端会逐步询问几个问题。第一个问题Generating public/private ed25519 key pair. Enter file in which to save the key (/Users/你的用户名/.ssh/id_ed25519):由于我们用了-f参数这里直接按回车即可会自动使用默认路径。第二个问题Enter passphrase (empty for no passphrase):这里的 passphrase 是私钥的额外保护密码。如果设置了每次使用私钥时都需要输入这个密码如果不设置直接按回车跳过私钥就是裸奔状态。我的建议是个人使用的 Mac 可以留空方便日常操作如果是公司配发的电脑或者有安全合规要求建议设置一个。设置后可以通过 ssh-agent 配合钥匙串实现免密后面会详细说。第三个问题让你再输一遍 passphrase 确认保持与之前一致即可。生成完成后终端会打印出密钥指纹和随机艺术图一张 ASCII 图案看到这些字符就说明密钥创建成功了。3.2 两种密钥算法的选型对比我知道有些朋友会有疑问网上教程都让用rsa为什么这里用ed25519确实早期的大多数 SSH 配置教程都以 RSA 为主因为 GitHub 对 RSA 的支持最成熟。但 RSA 密钥有一个明显短板密钥长度越长安全性越好但文件体积和 CPU 开销也越大。GitHub 官方文档目前推荐的默认算法就是 Ed25519它的安全性相当于 RSA 4096 位甚至更高但密钥长度只有 256 位生成和验证速度都快得多。如果你偏好保守方案用 RSA 也可以命令改成ssh-keygen -t rsa -b 4096 -C 你的邮箱example.com-b 4096表示密钥长度。GitHub 在 2022 年前后取消了 RSA 密钥最低长度限制现在 2048 位也能用但 4096 位更稳妥。两种方案我都实际用过结论是新配置一律用 Ed25519只有老系统、旧设备等兼容性要求苛刻的场景才考虑 RSA。毕竟这和 HTTPS 协议选择 TLS 1.3 是一个逻辑——能用新标准就用新标准安全性和效率都更好。3.3 私钥文件的权限管理密钥生成后一个容易被忽略但非常关键的细节是文件权限。SSH 对密钥文件的权限要求很严格如果私钥文件的权限过于开放SSH 会直接拒绝使用它。检查权限ls -l ~/.ssh/正常情况下私钥文件id_ed25519的权限应该是-rw-------也就是只有当前用户可读可写。公钥文件id_ed25519.pub的权限是-rw-r--r--这个无所谓。如果权限不对执行chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub600代表只有属主可读写644代表属主可读写、其他人可读。之所以公钥可以放宽权限是因为公钥本身就是要给别人看的而私钥必须私藏权限越紧越好。这一步不做后面测试连通性时会报Permissions 0644 for id_ed25519 are too open之类的错误排查起来很浪费时间。4. 将公钥添加到 GitHub 账号4.1 复制公钥内容公钥文件是.pub后缀的那个内容是一长串文本格式类似ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... 你的邮箱example.com复制内容有两种方式。一是直接查看文件内容后手动全选复制cat ~/.ssh/id_ed25519.pub选中输出内容Cmd C 复制。二是用 pbcopy 命令直接把文件内容复制到剪贴板pbcopy ~/.ssh/id_ed25519.pubpbcopy是 macOS 自带的命令作用是把标准输入的内容写入剪贴板。第二种方式更优雅不需要手动框选也不用担心漏掉末尾字符。复制后可以直接在任意地方 Cmd V 粘贴验证一下剪贴板里是不是完整的公钥内容。4.2 GitHub 网页端添加公钥的完整步骤打开 GitHub 官网并登录账号确保网络能正常访问 GitHub 页面。点击右上角头像选择Settings。在左侧菜单栏中找到SSH and GPG keys。点击绿色按钮New SSH key。在Title输入框给这个密钥起一个容易识别的名称。我的习惯是写“设备名 日期”比如MacBook Pro 2024-01。这样以后管理多台设备的密钥时一目了然。在Key输入框粘贴刚复制的公钥内容id_ed25519.pub文件里的全部内容。点击Add SSH key按钮完成添加。添加成功后GitHub 可能会要求输入账号密码确认操作输入后即可。这个流程我实操过很多次每个步骤的入口位置可能会随着 GitHub 改版略有变化但整体路径大差不差。4.3 验证 SSH 连接是否成功公钥添加完成后回到终端测试连接ssh -T gitgithub.com首次连接时终端会提示The authenticity of host github.com (IP地址) cant be established. ED25519 key fingerprint is SHA256:DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU. Are you sure you want to continue connecting (yes/no)?这是 SSH 在询问你是否信任这台服务器输入yes确认即可。这里建议认真看一眼指纹串GitHub 官方文档有对应的指纹记录可以核对一下防止中间人攻击。不过日常使用中大多数人直接回车确认也没问题。输入yes后如果看到Hi your_username! Youve successfully authenticated, but GitHub does not provide shell access.恭喜你SSH 认证已经打通。最后一步是把仓库的远程地址从 HTTPS 改成 SSH这样才能走 SSH 通道。在本地仓库中执行git remote -v查看当前远程地址。如果开头是https://github.com/...改成 SSH 格式git remote set-url origin gitgithub.com:你的用户名/仓库名.git改完后再次执行git remote -v确认地址应该变成gitgithub.com:开头。之后执行 push、pull 等操作都不再需要输入任何凭据。5. 进阶操作多账号管理与 ssh-agent 配置5.1 一台 Mac 管理多个 GitHub 账号的场景很多开发者的痛点在这里公司用企业版 GitHub 或 Gitee个人用的是 github.com两套账号有时还要同时操作。如果只生成一套密钥后生成的会覆盖之前的配置导致其中一个账号失效。解决办法是为每个账号生成独立的密钥文件再通过~/.ssh/config文件做路由。假设你有两个账号个人账号personalexample.com密钥文件~/.ssh/id_ed25519_personal公司账号workexample.com密钥文件~/.ssh/id_ed25519_work分别生成两套密钥注意-f参数指定不同文件名ssh-keygen -t ed25519 -C personalexample.com -f ~/.ssh/id_ed25519_personal ssh-keygen -t ed25519 -C workexample.com -f ~/.ssh/id_ed25519_work然后把两个公钥都添加到 GitHub或对应的代码托管平台上标题分别标注清楚。接下来编辑 SSH 配置文件nano ~/.ssh/config如果没有这个文件nano会直接创建。写入以下配置Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_personal Host github-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_work第一段Host github.com表示默认访问 github.com 时使用个人账号的密钥。第二段Host github-work是一个别名实际连接的服务器还是 github.com但使用公司账号的密钥。配套地克隆仓库时地址也要做区分个人仓库git clone gitgithub.com:用户名/仓库.git公司仓库git clone gitgithub-work:公司用户名/仓库.git注意公司仓库用的是别名github-work这样 SSH 才会匹配到对应的密钥文件。5.2 让 ssh-agent 在钥匙串中记住密钥如果你给私钥设置了 passphrase那么每次 push 代码时都会提示输入密码体验很差。解决办法是让 macOS 的钥匙串Keychain帮你记住。在 macOS 上使用--apple-use-keychain参数将密钥添加到 ssh-agent并同步存入钥匙串ssh-add --apple-use-keychain ~/.ssh/id_ed25519之后在~/.ssh/config中为对应 Host 添加以下配置Host github.com AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_ed25519UseKeychain yes是 macOS 专属配置只有装了 Command Line Tools 才能识别这个参数。配置后首次使用时输入一次 passphrase之后 SSH 会自动从钥匙串读取实现真正的免密操作。额外提一个坑如果你用的是旧版 macOS比如 10.12 之前的版本--apple-use-keychain参数可能会报错需要换成-K参数ssh-add -K ~/.ssh/id_ed25519macOS 新版本虽然兼容-K但官方已经推荐使用--apple-use-keychain建议优先用新版写法。5.3 配置零星注意事项多账号配置中容易踩的坑有两个。第一个是权限问题。~/.ssh/config文件的权限也不能太开放。改完配置后最好执行一下chmod 600 ~/.ssh/config否则 SSH 会提示bad permissions并忽略配置文件导致路由不生效。第二个是 ssh-agent 的清理。切换账号时如果 ssh-agent 里缓存了旧密钥可能选错密钥导致认证失败。可以先清空再重新添加ssh-add -D ssh-add --apple-use-keychain ~/.ssh/id_ed25519_personal ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work-D参数会删除 ssh-agent 中所有已缓存的密钥相当于重启干净状态。重新添加后系统会根据config文件自动选择合适的密钥。6. 常见问题与排查技巧实录6.1 Permission denied (publickey)这是最经典的报错出现概率极高。原因通常是以下几种公钥没有添加到 GitHub 账号。返回 Git 添加公钥的步骤检查一遍。添加的公钥和本机私钥不匹配。检查~/.ssh/目录下是否有多个私钥文件确认 GitHub 上添加的是对应公钥。SSH 没有使用正确的密钥。多账号场景下config 文件配置有误导致选错密钥。排查命令很有用ssh -vT gitgithub.com-v参数会输出详细的调试信息观察输出中Offering public key后面的密钥文件名就能知道当前用的是哪把私钥。如果是错误的密钥就会在Authentications that can continue: publickey提示后认证失败。6.2 修改密钥后仍然提示用户名或密码如果你刚把 push 方式改成 SSH终端却仍然弹出 GitHub 的用户名密码输入框多半是凭据被缓存了。Git 在 macOS 上默认使用 osxkeychain 辅助程序存储 HTTPS 凭据旧的 HTTPS 地址仍然被记录在钥匙串里。解决办法是清除缓存凭据git credential-osxkeychain erase hostgithub.com protocolhttps输入后按回车再按 CtrlD 结束输入。之后重新执行git remote -v确认远程地址是 SSH 开头问题就能解决。6.3 密钥验证时提示 Host key verification failed这个报错通常出现在重装系统或换了新设备后原因是你本机的~/.ssh/known_hosts中记录的 GitHub 服务器指纹和当前不一致。解决办法是删除 known_hosts 中对应的旧记录ssh-keygen -R github.com然后重新执行ssh -T gitgithub.com再次确认指纹信息即可。6.4 macOS 钥匙串权限弹窗使用--apple-use-keychain添加密钥后首次连接时系统会弹出“git 想要访问你的钥匙串”的提示。这属于正常安全机制填写用户密码并选择“始终允许”即可。如果之前误点了“拒绝”需要到 系统设置 隐私与安全 钥匙串访问 中手动授权。6.5 常见问题速查表报错信息可能原因解决办法Permission denied (publickey)公钥未添加或不匹配重新添加公钥检查密钥文件Host key verification failedknown_hosts 记录过期ssh-keygen -R github.comBad permissions私钥或配置文件权限过开chmod 600设置权限Could not open a connection网络无法访问 GitHub检查网络连通性Error: socket/Users/xx/.ssh/agent.sockssh-agent 进程异常重启 ssh-agent 服务7. 实操总结与我的经验之谈整套流程走下来核心操作其实只有四步生成密钥、添加公钥、测试连接、切换远程地址。但我在帮别人排查问题的过程中发现很多人恰恰是忽略了一些小细节导致反复卡壳。第一公钥和私钥必须配对使用。有人从别的电脑拷贝了私钥文件但公钥没有同步到 GitHub或者 GitHub 上已经存在旧公钥就会一直认证失败。最简单的验证方式是用ssh-add -l看本机是否已加载私钥再用ssh -T gitgithub.com验证。第二密钥文件路径别瞎改。默认路径~/.ssh/id_ed25519已经被 SSH 内置为默认查找位置。如果你用-f指定了别的路径后续每次操作 SSH 都要额外指定密钥路径很容易出错。非必要不折腾。第三macOS 的钥匙串是一个非常好用的功能但要注意它和 ssh-agent 是两个独立的东西。ssh-agent 负责进程内的密钥缓存钥匙串负责磁盘上的密码存储。理解了这个区别遇到“昨天还能免密今天突然要密码”的情况时你就知道先查 ssh-agent 状态而不是去重新配置。如果在这个配置过程中遇到什么问题欢迎留言交流我会把常见问题持续补充到这篇文章里。配置好的 SSH keys会让你后续和 GitHub 的每一次交互都顺畅很多。