![显示以 OpenSSH 格式存储的 ed22519 私钥的值](https://linux22.com/image/143816/%E6%98%BE%E7%A4%BA%E4%BB%A5%20OpenSSH%20%E6%A0%BC%E5%BC%8F%E5%AD%98%E5%82%A8%E7%9A%84%20ed22519%20%E7%A7%81%E9%92%A5%E7%9A%84%E5%80%BC.png)
(请注意,这个问题在文本中同时使用了“openssh”和“openssl”,我不会混淆两者。)
如果我使用 openssh 来通用 RSA 密钥对 (ssh-keygen),那么我可以使用“openssl rsa -in ...”来查看关键参数(模数、指数、素数等)。
如果我生成 RSA 密钥但使用 openssh 格式存储它(使用 ssh-keygen 的 -o 选项),我无法通过 openssl 直接读取该文件。我首先使用 ssh-keygen -p -f 并删除密码。生成的文件是“RSA 私钥”。然后我可以按照通常的方式使用 openssl 查看参数。
使用 openssl 的“ec”和“ecparam”命令,我可以生成文件并查看组成 EC 密钥的参数。
如果我使用 ssh-keygen -t ed25519 生成 ed25519 密钥对,我会得到一个格式为“OPENSSH PRIVATE KEY”的文件。
显然,如果我在这个文件上使用上面的“ssh-keygen -p ...”,我永远不会得到“RSA”输出,因为它不是 RSA 密钥。
那么如何将 ssh-keygen 使用 ed25519 生成的“OPENSSH PRIVATE KEY”文件转换为可以看到参数的格式?
openssl EC 命令生成诸如“BEGIN EC PARAMETERS”和“BEGIN EC PRIVATE KEY”之类的文件。
那么有没有办法查看OPENSSH PRIVATE KEY中的ed25519参数呢?或者一种将该文件格式转换为 openssl 可以理解的 EC 格式之一的方法?
答案1
长话短说:你不能转换为 OpenSSL
2021 年 2 月更新:您无法将 OpenSSH ed25519 密钥转换为 OpenSSL 支持的形式。在 Q 和原始 A 之日,OpenSSL 不支持任何存储形式的 ed25519 密钥,也不支持 Ed25519(或任何其他 EdDSA)算法。它确实支持 X25519 进行 TLS 密钥交换,但仅使用临时密钥,不需要任何存储格式。 OpenSSL 1.1.1 于 2018 年 9 月同月晚些时候发布,支持使用 PKCS8 格式私钥的 Ed25519 和 Ed448(以及 X25519 和 X448)。但是,ssh-keygen
(OpenSSH)不能写此 OpenSSL 兼容格式的 Ed25519 密钥,自 6.5 起,OpenSSL 无法读取用于它的 OpenSSH 专有格式(自 7.8 起,其他类型也是默认的)。
Ed25519不需要任何参数,并且OpenSSH密钥文件格式不为其存储任何参数; Ed25519 被定义为 Bernstein curve25519(以 Edwards 形式)的 EdDSA 实例化(参数化),它定义了所有需要的参数。有关详细信息,请参阅 RFC 8032 和 7748。
对于X9和SECG定义的EC算法标准称为 ECDSA 和 ECDH,OpenSSL 使用这些标准中定义的参数,这些参数仅支持带有以短 Weierstrass 形式表示的方程的椭圆曲线。 Bernstein 的 curve25519(和 curve448)使用 Montgomery 和 Edwards 形式代替,其原因在他的网站上的论文中进行了详细讨论,并且无论如何 EdDSA算法与ECDSA算法不同。但这已经不再重要了。
如果您不想在 OpenSSL 中使用密钥,而只是想知道它是什么,则ssh-keygen -y
已经以 OpenSSH 的首选形式输出公钥,即 ASCII 中的类型名称ssh-ed25519
加上 (SSH2) 有线格式的 base64 编码,依次为 4 字节长度 + 类型名称 + 4 字节长度 + 32 字节公钥(使用 RFC8032 中定义的编码)。如果您确实想要私钥,您可以首先使用以下命令解密文件ssh-keygen -p
(确保不要将任何副本放在不法分子可以获取的地方),然后使用以下命令转储od -tx1
:公钥 blob 从偏移量 053 开始,长度为 063(均为八进制),通常但现在未加密的部分从偏移量 0142 开始,长度为 0210 同上,即 8 字节检查,然后是私有“blob”,即 4字节长度 + 32 字节公钥副本 + 4 字节长度 + 64 字节 API“秘密”密钥,其中只有 32 字节是真正的私钥,其余的是公钥的另一个(!)副本,然后是 4 字节长度+评论。