首页 > 解决方案 > 从私钥生成的公钥在 2 种情况下不同

问题描述

我正在尝试生成私钥和公钥对。我想使用私钥签署我的 JWT 并将公钥发送给第 3 方以解码我的 JWT。

在我的 mac os 终端上,我生成了这样的密钥:

ssh-keygen -m PEM -t rsa -b 2048

现在我将 pkey 和 pkey.pub 分别作为私钥和公钥。现在在我的 Rails 控制台中,我尝试像这样获取私钥,效果很好:

rsa_private = OpenSSL::PKey::RSA.new(File.read("/path/to/private/key/pkey"))

rsa_private.to_s
"-----BEGIN RSA PRIVATE KEY-----\nCONTENTS_OF_PKEY_FILE\n-----END RSA PRIVATE KEY-----\n"

现在在 Rails 中,我可以像这样从生成的私钥中获取公钥:

pub_key = rsa_private.public_key

但是当我尝试打印它的内容时,它与我运行 ssh-keygen 命令时生成的 pkey.pub 中的内容不同。

pub_key 看起来像这样:

"-----BEGIN PUBLIC KEY-----\nSOME_CONTENT\n-----END PUBLIC KEY-----\n"

但我的 pkey.pub 文件看起来不同,如下所示:

ssh-rsa SOME_OTHER_CONTENT user@user.local

所以,我的问题是,我怎样才能为同一个私钥获得 2 个不同的公钥?我使用哪一个来解码我的 JWT?

标签: ruby-on-railsmacosopensslssh-keys

解决方案


密钥应该相同,但编码不同。

一个 RSA 密钥对由几个数字组成,私钥是所有这些数据,公钥与删除的私钥相同。

数字可以以不同的顺序书写,以不同的格式编码。还可以使用密码加密密钥以进行存储(不是这种情况)。因此,具有相同键的文件看起来可能完全不同。

PEM 格式(带有BEGIN PUBLIC KEYBase64 数据的格式)对于通用键更常见,因此最好使用它。

更新: PEM 格式是带有页眉和页脚的 base64 编码 DER。DER 又是 ASN.1 的二进制表示。但 SSH 使用 dirrerent 密钥编码格式 (RFC4716)

例子:

% ssh-keygen -m PEM -t rsa -N '' -b 1024 -f ./rsa

% cat rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDRNFYxsULk6x90T0EE8iS3skfJJ407ef3WJJClre0k2sLJUJX6/Xbc3ObxNjixXcgIXp2H4oVOnNpujqFF/XM81zlpLjGT/4igtK1FjIHIaFyRheGuwplgwCkXlxAe/oH1Bb4nFXlD/kORmGgSfSE9BpH+HQU3IzyU1i0X9K828Q== vasfed@Vasiliys-MacBook-Pro.local

% ssh-keygen -e -m PEM -f ./rsa.pub
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBANE0VjGxQuTrH3RPQQTyJLeyR8knjTt5/dYkkKWt7STawslQlfr9dtzc
5vE2OLFdyAhenYfihU6c2m6OoUX9czzXOWkuMZP/iKC0rUWMgchoXJGF4a7CmWDA
KReXEB7+gfUFvicVeUP+Q5GYaBJ9IT0Gkf4dBTcjPJTWLRf0rzbxAgMBAAE=
-----END RSA PUBLIC KEY-----

% ssh-keygen -e -m PKCS8 -f ./rsa.pub
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRNFYxsULk6x90T0EE8iS3skfJ
J407ef3WJJClre0k2sLJUJX6/Xbc3ObxNjixXcgIXp2H4oVOnNpujqFF/XM81zlp
LjGT/4igtK1FjIHIaFyRheGuwplgwCkXlxAe/oH1Bb4nFXlD/kORmGgSfSE9BpH+
HQU3IzyU1i0X9K828QIDAQAB
-----END PUBLIC KEY-----

以上是同一密钥的 3 种不同编码,这里是后两者的 ASN 解码版本(通过https://lapo.it/asn1js):

PEM,最低限度(模数和指数,无元数据):

SEQUENCE (2 elem)
  INTEGER (1024 bit) 146908353891476107599563957703741990254320034409224509383359005248419…
  INTEGER 65537

PKCS8,在这里我们看到完全相同的数字,但这次有一些元数据:

SEQUENCE (2 elem)
  SEQUENCE (2 elem)
    OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
    NULL
  BIT STRING (1 elem)
    SEQUENCE (2 elem)
      INTEGER (1024 bit) 146908353891476107599563957703741990254320034409224509383359005248419…
      INTEGER 65537

推荐阅读