openssl 生成的公私钥和 ssh-keygen 生成的公私钥的区别和联系

发布时间: 更新时间: 总字数:1700 阅读时间:4m 作者: IP上海 分享 网址

openssl 和 ssh-keygen 都是生成和管理加密密钥的工具,但它们各有侧重,因此生成的公私钥在默认格式和主要应用场景上存在区别,同时又通过可转换性建立了联系。

区别

主要用途和哲学

  • openssl: 是一个功能更全面、更底层的密码学工具包,它支持广泛的加密算法和协议(如 RSA, ECC, DSA, AES, SHA 等),并处理各种标准化的密钥和证书格式(如 PEM, DER, PKCS#1, PKCS#8, X.509)
    • 它更常用于构建 PKI(Public Key Infrastructure),例如生成 SSL/TLS 证书、代码签名、加密通信等
    • 它的设计更注重密码学原语和标准遵从性
  • ssh-keygen: 专门用于 SSH (Secure Shell) 协议 的密钥管理
    • 它的主要目的是生成用于 SSH 身份验证的密钥对
    • 虽然它也支持多种算法(RSA, ECDSA, Ed25519),但其输出格式和操作流程都围绕 SSH 协议的特定需求进行优化

默认密钥格式

  • openssl 生成的密钥
    • 私钥: 默认生成的是 PEM (Privacy-Enhanced Mail) 格式
      • 对于 RSA,通常是 -----BEGIN RSA PRIVATE KEY----- (PKCS#1) 或 -----BEGIN PRIVATE KEY----- (PKCS#8)
      • 对于 EC,通常是 -----BEGIN EC PRIVATE KEY----------BEGIN PRIVATE KEY-----
      • 这些格式是通用的,被许多密码学库和应用程序广泛支持
    • 公钥: 默认生成的是 PEM 格式,通常是 -----BEGIN PUBLIC KEY----- (X.509 SubjectPublicKeyInfo) 或 -----BEGIN RSA PUBLIC KEY----- (PKCS#1 for RSA)
  • ssh-keygen 生成的密钥
    • 私钥: 默认生成的是 OpenSSH 自己的私钥格式(自 OpenSSH 7.8 版本开始)
      • 这种格式以 -----BEGIN OPENSSH PRIVATE KEY----- 开头
      • 这种格式相对于传统的 PEM 格式,通常具有更好的安全性(例如,更强的密钥派生函数)
    • 公钥: 默认生成的是 OpenSSH 公钥格式,这是一种单行文本格式,简洁明了,专门为 ~/.ssh/authorized_keys 文件设计
      • 例如:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... user@hostnameecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBB... user@hostname

密钥派生函数和加密强度(针对带密码的私钥)

  • openssl 在加密私钥时通常使用较传统的 PKCS#5v1.5 或 PKCS#5v2.0 的密钥派生函数(如 PBKDF1 或 PBKDF2),其迭代次数可能相对较低
  • ssh-keygen 新的 OpenSSH 格式在加密私钥时使用了更现代、更安全的 KDF(Key Derivation Function),通常采用更长的盐和更高的迭代次数,这使得暴力破解带密码的私钥变得更加困难

联系

尽管存在上述区别,opensslssh-keygen 生成的公私钥在底层加密数据上是相同的,并且可以互相转换

  • 底层数据相同
    • 无论是由 openssl 还是 ssh-keygen 生成,一个 RSA 密钥对的核心是相同的数学参数(例如,RSA 的模数 n 和公钥指数 e,私钥指数 d 等;ECDSA 的椭圆曲线参数和私钥整数 d)
    • 不同之处在于这些核心参数被编码和封装在不同的文件格式中
  • 格式转换
    • ssh-keygen 提供了 -m (format) 参数来指定输出或输入密钥的格式,允许你在 OpenSSH 格式和 PEM 格式之间进行转换
    • openssl 也可以用于导入和导出不同格式的密钥,例如从 PEM 私钥中提取公钥,或者将私钥转换为 PKCS#8 格式

实际应用

  • SSH 登录: 如果你仅仅是为了进行 SSH 登录,强烈建议使用 ssh-keygen。它生成的密钥格式是 SSH 客户端和服务器原生支持的,并且新的 OpenSSH 格式提供了更好的安全性
  • SSL/TLS 证书、PKI 应用: 如果你需要为网站生成 SSL/TLS 证书、进行代码签名或开发其他需要通用 PKI 标准的应用,那么 openssl 是更合适的工具。它生成的 PEM 格式是这些应用的首选
  • 兼容性需求: 如果你的应用需要在不同的系统或服务之间共享密钥,并且它们对密钥格式有严格要求,那么理解这些格式的区别和转换方法就至关重要

相互转化示例

RSA

$ dpkg -l | grep openssh-client
ii  openssh-client                                1:9.6p1-3ubuntu13 ...

# 生成 SSH RSA 公私钥
$ ssh-keygen -t rsa

$ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC...
-----END OPENSSH PRIVATE KEY-----
$ cat id_rsa.pub
ssh-rsa AAAAB3Nza... root@ubuntu

# 将 OpenSSH 私钥转换为传统的 PEM (PKCS#1) 格式,源文件覆盖
# -p 表示修改密码,-m PEM 指定输出格式为 PEM,-f 指定输入文件
$ ssh-keygen -p -m PEM -f ./id_rsa
$ cat ./id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIG5QI...
-----END RSA PRIVATE KEY-----

# PKCS#8 格式,源文件覆盖
$ ssh-keygen -p -f id_rsa -m PKCS8
$ cat ./id_rsa
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

$ openssl rsa -in ./id_rsa -check
RSA key ok
writing RSA key
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

# 从 OpenSSH 公钥转换为 PEM 公钥
$ ssh-keygen -e -f ./id_rsa.pub -m PEM > public_key.pem
$ cat public_key.pem
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

$ ssh-keygen -e -f ./id_rsa.pub -m PKCS8 > public_key2.pem
$ cat public_key2.pem
-----BEGIN PUBLIC KEY-----
MIIBoj...
-----END PUBLIC KEY-----

# PEM 私钥提取公钥,与 public_key2.pem 一致
$ openssl rsa -pubout -in id_rsa
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBoj...
-----END PUBLIC KEY-----

# PEM 私钥转换为 OpenSSH 格式
$ ssh-keygen -p -f ./id_rsa -m OpenSSH

# 从 PEM 私钥中提取 OpenSSH 私钥
$ ssh-keygen -p -m RFC4716 -f id_rsa
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
$ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----

ecdsa

$ ssh-keygen -t ecdsa
$ cat id_ecdsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNz...
-----END OPENSSH PRIVATE KEY-----
$ cat id_ecdsa.pub
ecdsa-sha2-nistp256 AAAAE2VjZHN... root@ubuntu

# 将 OPENSSH 私钥转化为 PKCS8 私钥
$ ssh-keygen -p -f id_ecdsa -m PKCS8
$ cat id_ecdsa
-----BEGIN PRIVATE KEY-----
MIG...
-----END PRIVATE KEY-----

# 从 PKCS8 私钥提取公钥
$ openssl ec -pubout -in id_ecdsa
read EC key
writing EC key
-----BEGIN PUBLIC KEY-----
MFkwEw...
-----END PUBLIC KEY-----

# 从 OPENSSH 公钥提取公钥,与上面的内容相同
$ ssh-keygen -e -f ./id_ecdsa.pub -m PKCS8
-----BEGIN PUBLIC KEY-----
MFkw...
-----END PUBLIC KEY-----

# 从 PKCS8 私钥转化为 OPENSSH 私钥
$ ssh-keygen -p -m RFC4716 -f id_ecdsa
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
$ cat id_ecdsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnN...
-----END OPENSSH PRIVATE KEY-----

# 重新转化回来的 SSH 私钥内容可能不同,但私钥指纹相同
$ ssh-keygen -l -f id_ecdsa
256 SHA256:vZnPzQ5r/otPaIor1B4cUliDmwGQBIZpACLG4XarEXk root@ubuntu (ECDSA)
$ ssh-keygen -l -f id_ecdsa.bak
256 SHA256:vZnPzQ5r/otPaIor1B4cUliDmwGQBIZpACLG4XarEXk root@ubuntu (ECDSA)
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数