从私钥生成的公钥在 2 种情况下不同
Posted
技术标签:
【中文标题】从私钥生成的公钥在 2 种情况下不同【英文标题】:Generated public key from private key different in 2 cases 【发布时间】:2019-09-15 02:03:09 【问题描述】:我正在尝试生成私钥和公钥对。我想使用私钥对我的 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?
【问题讨论】:
【参考方案1】:密钥应该相同,但编码不同。
一个 RSA 密钥对由多个数字组成,私钥就是所有这些数据,公钥与删除的私钥相同。
数字可以以不同的顺序书写,以不同的格式编码。还可以使用密码加密密钥以进行存储(不是这种情况)。因此,具有相同键的文件看起来可能完全不同。
PEM 格式(带有BEGIN PUBLIC KEY
和 Base64 数据的格式)更常见于通用键,因此最好使用它。
更新: PEM 格式是带有页眉和页脚的 base64 编码的 DER。 DER 又是 ASN.1 的二进制表示。但是 SSH 使用了一种直接的密钥编码格式 (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
【讨论】:
虽然您的答案可能是非常笼统的,但BEGIN PUBLIC KEY
和 .pub
格式都使用相同的编码,所以它们应该是相同的(除了 BEGIN PUBLIC KEY
有标题/trailer 并换行,而 .pub
没有)。
@MartinPrikryl SSH 使用 RFC4716,而 ruby 使用 PKCS 编码,请参阅更新示例
好的。与.pub
使用相同编码的多行格式为BEGIN SSH2 PUBLIC KEY
。以上是关于从私钥生成的公钥在 2 种情况下不同的主要内容,如果未能解决你的问题,请参考以下文章