在 openssl 和 openssh 之间转换密钥

信息安全 SSH openssl
2021-08-13 07:35:51

如果我使用以下

openssl req -x509  -days 365 -newkey rsa:2048 -keyout private.pem -out public.pem -nodes

我得到private.pem并且public.pem

如果我使用

ssh-keygen -t rsa -f rsa

我得到rsa并且rsa.pub

是否可以从 to 的格式转换,rsa反之亦然private.pem

编辑:更具体地说,

a) 如果我有上述命令生成的private.pemand public.pem,我如何获得等效的 rsa 私钥和公钥?

b) 给定rsaand rsa.pub,如果我知道上述 openssl 命令接收的附加元数据,我如何获得 x509 密钥?

如果我从 openssh 格式转到 x509 并返回,理想情况下我应该得到相同的密钥文件。

4个回答

你在这里遗漏了一点。

ssh-keygen可用于将公钥从 SSH 格式转换为适合 OpenSSL 的 PEM 格式。私钥通常已经以适合两者的 PEM 格式存储。

但是,您显示的 OpenSSL 命令会生成自签名证书这个证书不是 OpenSSH 传统上用于任何东西的东西——而且它绝对不仅仅是一个公钥。

OpenSSH 也支持证书,但您可能没有使用此支持。此外,这些证书不是 X.509,因此它们与 OpenSSL 不兼容。

证书包含其他任何地方都不存在的信息,并且每个证书都是唯一的,不能随意重新创建。这意味着,如果您希望对 OpenSSL 和 OpenSSH 使用相同的密钥,除了私钥之外,您还需要存储 X.509 证书。


如果您只想共享私钥,您的示例命令生成的 OpenSSL 密钥存储在 中private.pem,并且它应该已经是与(最近的)OpenSSH 兼容的 PEM 格式。要从中提取与 OpenSSH 兼容的公钥,您只需运行:

ssh-keygen -f private.pem -y > private.pub

如果您想从 OpenSSH 开始,并使用自签名证书(无论出于何种原因)进入 OpenSSL 端,方法如下:

$ ssh-keygen -f test-user
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in test-user.
Your public key has been saved in test-user.pub.
The key fingerprint is:
ff:36:f1:74:c7:0d:4e:da:79:5c:96:27:2c:2c:4e:b6 naked@tink
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|           . .  .|
|          + o =.+|
|        S+ o * B+|
|         .E o = B|
|          .  + o.|
|           .o .  |
|           ...   |
+-----------------+
$ openssl req -x509 -days 365 -new -key test-user -out test-user-cert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
$ ls -l test-user*
-rw------- 1 naked naked 1675 Mar 18 21:52 test-user
-rw-r--r-- 1 naked naked 1229 Mar 18 21:53 test-user-cert.pem
-rw-r--r-- 1 naked naked  392 Mar 18 21:52 test-user.pub

从这些中,test-usertest-user-cert.pem文件对于保留至关重要,test-user.pub可以根据需要始终从测试用户重新创建。

openssh的ssh-keygen工具可以为您做到这一点。

以下命令将为您将.pub文件转换为pem格式。

ssh-keygen -f rsa.pub -e -m pem

还支持转换成各种其他格式,ssh-keygen更多信息请参见手册页。

较新版本的 OpenSSL(至少 >= 1.0.1)使用 PKCS#8 格式的密钥。

因此,如果您使用命令从证书中提取公钥

openssl x509 -in certificate.pem -noout -pubkey >pubkey.pem

您需要使用以下命令将其转换为 authorized_keys 条目

ssh-keygen -i -m PKCS8 -f pubkey.pem

OpenSSL 的req命令的-out选项产生证书请求而不是公钥。

要提取 PKCS#8 格式的公钥,可以通过ssh-keygen的导入功能使用以下命令来理解。

openssl req -in public.pem -noout -pubkey

可以使用以下命令将 2048 位公共 RSA 密钥从 X.509 PEM 格式转换为 OpenSSH 格式(参见answer)。给定来自链接答案的信息,在另一个方向上编写转换并不难。

echo -n "ssh-rsa " > rsa2048.pub
grep -v -- ----- rsa2048.pem | base64 -d | dd bs=1 skip=32 count=257 status=none | xxd -p -c257 | sed s/^/00000007\ 7373682d727361\ 00000003\ 010001\ 00000101\ / | xxd -p -r | base64 -w0 >> rsa2048.pub
echo >> rsa2048.pub