遇到 Git 报错 permission denied (publickey) 时,最推荐的处理方向是重新生成 SSH 密钥对并将公钥上传至代码托管平台,适用场景为本地密钥丢失、损坏或从未配置过 SSH 连接,重要风险边界是重新生成密钥后,旧密钥将失效,需同步更新所有使用该密钥的 CI/CD 流程或其他设备。
先说结论:重新生成密钥是解决 SSH 认证失败的有效手段,但需确保新公钥已正确添加到 Git 平台账户设置中。
- 先确认:检查本地 ~/.ssh 目录是否已存在可用密钥,避免重复生成。
- 先处理:使用 ssh-keygen 生成新密钥对,并将公钥内容复制到 Git 平台 SSH 设置页面。
- 再验证:通过 ssh -T 命令测试连接,确认返回欢迎信息即表示配置生效。
命令速用版
以下命令适用于 Linux、macOS 及 Windows Git Bash 环境,可直接复制执行。
# 1. 生成新密钥(推荐 ed25519 算法)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 2. 启动 ssh-agent 并添加密钥
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# 3. 复制公钥内容
cat ~/.ssh/id_ed25519.pub
# 4. 测试连接(以 GitHub 为例)
ssh -T git@github.com
为什么会这样
报错核心原因是本地私钥与 Git 平台存储的公钥不匹配,或 SSH 代理未加载密钥。
Git 使用 SSH 协议进行身份验证时,会发送本地私钥签名,Git 平台用存储的公钥验证。如果本地没有私钥、私钥权限错误、或者平台没有对应的公钥,都会返回 permission denied (publickey)。此外,ssh-agent 未运行或未加载密钥也会导致验证失败。
分步处理
按顺序执行以下步骤,每步完成后检查是否有报错。
步骤 1:检查现有密钥
执行 ls -al ~/.ssh 查看是否已有 id_rsa 或 id_ed25519 文件。如果有且确认不可用,可备份后删除;如果没有,直接进入步骤 2。
步骤 2:生成新密钥对
运行 ssh-keygen -t ed25519 -C "your_email@example.com"。提示保存路径时直接回车默认,提示 passphrase 时可回车留空或设置密码。注意邮箱地址需与 Git 平台账户邮箱一致。
步骤 3:添加密钥到代理
执行 eval "$(ssh-agent -s)" 启动代理,然后执行 ssh-add ~/.ssh/id_ed25519。如果提示权限问题,执行 chmod 600 ~/.ssh/id_ed25519 修复。
步骤 4:上传公钥到平台
执行 cat ~/.ssh/id_ed25519.pub 复制输出内容。登录 GitHub/GitLab 网站,进入 Settings -> SSH Keys,点击 New SSH Key,粘贴内容并保存。切勿复制私钥文件。
步骤 5:测试连接
执行 ssh -T git@github.com(GitLab 用户用 ssh -T git@gitlab.com)。首次连接会提示确认指纹,输入 yes 继续。
怎么验证是否生效
验证成功的标志是终端返回包含用户名的欢迎信息,而非 Permission denied。
例如 GitHub 会显示 Hi username! You've successfully authenticated, but GitHub does not provide shell access.。如果仍然报错,检查 Git 远程地址是否为 SSH 格式(git@github.com:user/repo.git),而非 HTTPS 格式。
常见坑
- 权限过于开放:~/.ssh 目录权限应为 700,私钥文件应为 600,否则 SSH 会拒绝使用密钥。
- 复制了私钥:上传到 Git 平台的必须是 .pub 结尾的公钥内容,私钥泄露会导致安全风险。
- 多密钥冲突:如果 ~/.ssh/config 中配置了多个 Host,确保 Git 使用的 Host 指向了正确的 IdentityFile。
- CI/CD 失效:重新生成密钥后,所有依赖旧私钥的自动化流程(如 Jenkins、GitHub Actions)都会失败,需更新部署密钥。
常见问题
重新生成密钥后需要修改 Git 用户邮箱吗?
不需要修改 Git 配置邮箱,但生成密钥时 -C 参数建议填写与 Git 平台账户一致的邮箱,方便识别密钥用途。
每次重启电脑都要重新 ssh-add 吗?
默认情况下是的,但可以在 ~/.ssh/config 中配置 AddKeysToAgent yes 并设置 UseKeychain(macOS)或集成系统密钥环来实现持久化。
如果只用 HTTPS 协议还需要生成 SSH 密钥吗?
不需要,HTTPS 协议使用用户名密码或 Personal Access Token 认证,SSH 密钥仅用于 SSH 协议连接。
参考来源
- GitHub Docs: Connecting to GitHub with SSH - https://docs.github.com/en/authentication/connecting-to-github-with-ssh
- GitLab Docs: SSH keys - https://docs.gitlab.com/ee/user/ssh.html
- Atlassian Bitbucket: Set up SSH for Git - https://support.atlassian.com/bitbucket-cloud/docs/set-up-ssh-for-git/