ssh-keygen是ssh登录首选工具,生成rsa密钥对(如-t rsa -b 4096),默认输出id_rsa和id_rsa.pub,权限自动设为600/644,兼容openssh;而openssl适用于https等非ssh场景,但需手动处理格式与权限。

ssh-keygen 是最常用、最稳妥的选择,直接生成符合 SSH 协议的 RSA 密钥对,开箱即用,无需后续转换。
用 ssh-keygen -t rsa 生成标准 SSH 密钥对
这是面向 SSH 登录场景的首选方式,生成的密钥默认兼容 OpenSSH 服务端(sshd),且权限和格式一步到位。
-
ssh-keygen -t rsa -b 4096比默认 2048 位更安全,推荐使用;-b参数必须显式指定,否则老版本可能仍用 2048 - 私钥保存为
~/.ssh/id_rsa,公钥为~/.ssh/id_rsa.pub,路径和文件名是 OpenSSH 默认识别位置 - 若跳过 passphrase(直接回车),私钥文件不加密;但生产环境建议设密码,否则私钥一旦泄露即等同于账户失守
- 生成后自动设置
id_rsa权限为600,id_rsa.pub为644—— 这步不可省,sshd会因权限过宽拒绝加载密钥
用 openssl genrsa 生成通用 PEM 格式密钥
当你需要密钥用于非 SSH 场景(比如 HTTPS 证书、Java 应用签名、自建 CA)时,openssl 更灵活,但格式需手动适配。
-
openssl genrsa -out private.key 4096生成无密码保护的 PEM 私钥;加-aes256 -passout pass:xxx可加密,但 SSH 不认这种加密格式 - 公钥需额外导出:
openssl rsa -in private.key -pubout -out public.key,注意输出的是-----BEGIN PUBLIC KEY-----开头的 PKIX 格式,不是 SSH 所需的ssh-rsa AAAA...行格式 - 若要把 OpenSSL 公钥转成 SSH 格式,得用:
ssh-keygen -f public.key -i -m PKCS8(要求 OpenSSL 1.0.2+ 和较新 OpenSSH) - OpenSSL 默认不设文件权限,生成后务必手动执行
chmod 600 private.key,否则多数工具(包括ssh-add)会拒绝读取
为什么 ssh-keygen 生成的公钥不能直接给 OpenSSL 工具用?
因为两者公钥编码格式不同:SSH 使用 base64 编码的 ssh-rsa 线性字符串(含算法标识),OpenSSL 默认输出的是 ASN.1/DER 编码的 PKIX SubjectPublicKeyInfo 结构(PEM 封装)。二者不互通。
- 错误现象:
openssl rsautl -verify -inkey public.key -pubin报错unable to load key,大概率是公钥格式不对 - 验证是否为 SSH 格式:用
head -1 ~/.ssh/id_rsa.pub,应看到类似ssh-rsa AAAAB3NzaC1yc2E... - 验证是否为 PEM 格式:用
head -2 public.key,应看到-----BEGIN PUBLIC KEY----- - 混用场景(如 Java 验签)必须用 OpenSSL 生成的 PEM 公钥,
ssh-keygen生成的不能直接喂给java.security.KeyFactory
容易被忽略的权限和路径细节
权限问题导致“密钥明明存在却登录失败”是最常见的线上故障点,尤其在 root 用户或容器环境中。
-
~/.ssh目录权限必须 ≤700(即drwx------),否则sshd直接忽略整个目录 -
authorized_keys文件权限必须是600,哪怕内容完全正确,644也会被拒绝 - 如果私钥不在默认路径(比如用了
-f /path/to/key),SSH 客户端不会自动加载,必须显式指定:ssh -i /path/to/key user@host - 在 systemd 服务或 cron 中调用 SSH 时,
$HOME可能未正确定义,导致~/.ssh路径解析失败 —— 建议始终用绝对路径
ssh-keygen;做 HTTPS、签名、CA 或对接其他语言生态,就用 openssl genrsa,并留心格式和权限。











