我正在尝试生成 RSA 密钥以通过 ssh 访问 azure 中的某些 git 存储库。
有了 Ubuntu22.04
和 OpenSSL 版本OpenSSL 3.0.2 15 Mar 2022
,
我生成了一个这样的 RSA 密钥:
$ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/me/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/me/.ssh/id_rsa
Your public key has been saved in /home/me/.ssh/id_rsa.pub
The key fingerprint is:
...
The keys randomart image is:
+---[RSA 4096]----+
....
....
+----[SHA256]-----+
但是当我这样做时
$ cat ~/.ssh/id_rsa
,我看到我的密钥文件以以下内容开头:
-----BEGIN OPENSSH PRIVATE KEY-----
应该是吗BEGIN RSA PRIVATE KEY
?有什么区别?
答案1
应该吗
不,不是真的。唯一的“应该”是它应该是一种ssh
自己可以理解的格式。(私钥永远不会发送到服务器,因此不存在与 Azure 兼容性的问题——它只需要与您的客户端兼容。)因此,您当前拥有的密钥格式是正确的;如果您的 ssh-keygen 生成了它,那么您的 ssh 客户端将能够使用它。
在文件中存储 SSH 私钥没有标准格式;每个 SSH 客户端可能使用自己的格式,实际上可能有 4 或 5 种不同的格式。以前 OpenSSH(程序ssh
)只是正巧使用 PKCS#1 格式,因为 OpenSSL 库已经对其自己的私钥使用了相同的格式,并提供了以这种格式加载和存储密钥的便捷函数。
然而,OpenSSH 没有想依赖于 OpenSSL – 毕竟,SSH 本身并不以任何方式基于 SSL/TLS;OpenSSH 使用 OpenSSL 的唯一原因是它的加密功能(libcrypto,例如 RSA 或 AES)– 因此它最终创建了自己的私钥格式,最初仅适用于 Ed25519 密钥,但最终开始将其用于所有算法。(尽管它仍然理解旧格式。)
请注意,无论文件格式如何,实际的“密钥”(例如 RSA 素数或 EC 点)仍然以相同的方式工作,因此如果需要,您可以轻松地从一种格式转换为另一种格式(使用ssh-keygen -p -m
或 PuTTY 的puttygen
工具)。
有什么不同?
PKCS#1 密钥文件 ( BEGIN RSA PRIVATE KEY
) 来自 PEM 加密消息项目。该格式相当过时,例如,它对密码暴力破解的防御能力较弱。甚至 OpenSSL 本身后来也开始对所有新私钥使用较新的 PKCS#8 格式(使用BEGIN PRIVATE KEY
或BEGIN ENCRYPTED PRIVATE KEY
标头)。
然而,PKCS#1 和 PKCS#8 格式在内部都使用 ASN.1,这是一种相当复杂的数据序列化方法——对于 TLS 软件来说这仍然是可以接受的,因为它们无论如何都需要 ASN.1 支持来解析 TLS 证书,但对于 SSH 客户端来说,它只会带来对 OpenSSL 的另一个不必要的依赖。
此外,它们的发展也主要由 TLS 和 X.509 证书驱动,这与 SSH 完全不同——例如,当 OpenSSH 首次获得对 Ed25519 密钥的支持时,它不能使用 OpenSSL 现有的函数来存储它们,因为该算法尚未被 TLS 世界采用;尚未分配算法 ID,数据格式尚未达成一致。
因此,OpenSSH 创建了自己的私钥存储格式(带有BEGIN OPENSSH PRIVATE KEY
标头的格式),它使用与 SSH 本身相同的结构和算法标识符,这意味着 SSH 支持的任何密钥都可以存储在 OpenSSH 密钥格式中 - 并且可以加载/存储它们而不再依赖 SSL/TLS 库。
(出于类似的原因,PuTTY 也有自己的“PPK”密钥格式,也是为了避免使用复杂的外部库。)