使用RSA私钥生成公钥?


394

我不太了解这一点:

根据:http : //www.madboa.com/geek/openssl/#key-rsa,您可以从私钥生成公钥。

openssl genrsa -out mykey.pem 1024
openssl rsa -in mykey.pem -pubout > mykey.pub

我最初的想法是它们是成对出现的。RSA私钥是否包含总数?还是公钥?


1
对于每个使用rsa和openssl并希望加密5 KB的大文件的人。请记住,公钥的大小应与要加密的大小成比例或更大,否则会出现“文件太大而无法加密的错误”。总结一下,您会生成一个相当大且严重的私钥,并由此生成私钥,以便可以使用大量数据。我在openssl中告诉我认识的漏洞,他们应该自行使其循环,否则您将花费​​大量时间弄清楚为什么它抱怨尺寸。
肯特·汉森

10
肯特·汉森(Kent Hansen)描述的问题是由于直接在明文数据上使用了RSA,出于安全原因,在任何情况下都不应这样做。取而代之的是使用经过充分分析的混合加密方案,例如RSA-KEM(tools.ietf.org/html/rfc5990#appendix-A),并将经过身份验证的对称加密方案(例如,先加密再加密HMAC)应用于数据。
Daira Hopwood 2013年



@SteffenUllrich在此链接中的答案解释了原因:security.stackexchange.com/questions/172274/…–
bearzyj

Answers:


577
openssl genrsa -out mykey.pem 1024

实际上会产生一个公钥-私钥对。该对存储在生成的mykey.pem文件中。

openssl rsa -in mykey.pem -pubout > mykey.pub

将提取公钥并打印出来。这里是一个链接的页面,它对此进行了更好的描述。

编辑:在此处检查示例部分。要仅输出私钥的公共部分:

openssl rsa -in key.pem -pubout -out pubkey.pem

要获得用于SSH的可用公共密钥,请使用ssh-keygen

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

50
令人困惑的是,各地教程中的每个人都在说,使用openssl genrsa命令将生成私有密钥,因为他们忘记了它也正在生成公共密钥
Jaime Hablutzel 2012年

15
@jaime真的可以怪他们吗?官方文档绝对没有公开密钥。“说明:genrsa命令生成一个RSA私钥。” openssl.org/docs/apps/genrsa.html
Despertar

124
@jaime,这是因为它不会-genrsa只生成私钥,而不会存储公钥。但是,如果您有私钥,则可以从中计算(推导)公钥-这是上面第二条命令所做的。它计算而不是提取公钥。
steveayre

13
@steveayre这是我的理解是,RSA密钥是简单的两个指数(ed在公共文献)。数学上的任何人都不是私人的,也不是公共的,它们是在创建时随意分配的标签。可以很容易地将它们反向分配。从另一个生成一个是等效的问题。该.pem格式包含了一大堆的资料,包括两个指数,所以这两个键,对不对?
lynks 2013年

13
@steveayre主要是错误的。DO的公共RSA密钥组件(n,e)随同生成,并嵌入到使用openssl genrsacommand 创建的私有RSA密钥文件中。但是,不会在同一步骤中创建单独的公共密钥文件。要将私钥文件中的公钥提取到单独的公钥文件中,请使用openssl rsa -in private.pem -pubout -out public.pem命令。当您以这种方式产生公钥时,它是从私钥文件中提取出来的,而不是计算出来的。请参阅下面的我的答案以获取更多详细信息。
golem

273

正在寻找SSH公钥的人...

如果您希望提取公钥以用于OpenSSH,则需要以其他方式获取公钥

$ ssh-keygen -y -f mykey.pem > mykey.pub

此公钥格式与OpenSSH兼容。将公钥附加到remote:~/.ssh/authorized_keys,您就可以使用了


来自的文档 SSH-KEYGEN(1)

ssh-keygen -y [-f input_keyfile]  

-y此选项将读取私有的OpenSSH格式文件,并将OpenSSH的公共密钥输出到stdout。


3
这就像一个魅力!它生成Github需要的格式!Github不采用PEM格式,之前的建议openssl rsa -in key.pem -pubout -out pubkey.pem并未被接受,因为它的输出显然是pem格式的公钥。所以我得到了这个错误:“密钥无效。它必须以'ssh-rsa'或'ssh-dss'开头。请检查您是否正在复制密钥的公用部分”。但是会ssh-keygen -y [-f input_keyfile] 生成Github所采用的正确格式。
Devy

71

在大多数生成RSA私钥的软件中,包括openssl,该私钥都表示为PKCS#1 RSAPrivatekey对象或其某些变体:

A.1.2 RSA私钥语法

RSA私钥应使用ASN.1类型
RSAPrivateKey表示:

  RSAPrivateKey ::= SEQUENCE {
      version           Version,
      modulus           INTEGER,  -- n
      publicExponent    INTEGER,  -- e
      privateExponent   INTEGER,  -- d
      prime1            INTEGER,  -- p
      prime2            INTEGER,  -- q
      exponent1         INTEGER,  -- d mod (p-1)
      exponent2         INTEGER,  -- d mod (q-1)
      coefficient       INTEGER,  -- (inverse of q) mod p
      otherPrimeInfos   OtherPrimeInfos OPTIONAL
  }

如您所见,此格式具有许多字段,包括模数和公用指数,因此是RSA公钥中信息的严格超集。


您是说给定私钥,从数学上讲可以生成公钥吗?RSA的优势不在于它在计算上不能给定另一个密钥的事实吗?
拉姆

30
@Raam:不,RSA的优势在于从公共场所生成私钥是不可行的。产生公共形式的私人是微不足道的。
总统詹姆斯·波尔克(James K. Polk)

@GregS,为什么?键由模数和指数组成。如果可以从这两个数字计算出其他指数,则RSA很容易破解。那么,OpenSSL私钥是否包含指数和模数?
Calmarius 2014年

1
@Calmarius:谁说钥匙由模数和指数组成?那将是最小的私钥,但通常,私钥包括其他组件,例如主要因素。详细阅读答案。
总统詹姆斯·波尔克(James K. Polk)2014年

1
@JamesKPolk不一定是正确的。如果公共指数很大(即具有与私有指数相同的属性),则可能无法重建公共密钥。大多数库都不支持此功能,但是RSA密码系统当然不需要您从私钥中重建公钥。
Maarten Bodewes

34

我在下面的回答有点冗长,但是希望它提供了先前回答中所缺少的一些细节。我将从一些相关的陈述开始,最后回答最初的问题。

要使用RSA算法加密某些内容,您需要模数和加密(公共)指数对(n,e)。那就是你的公钥。要使用RSA算法解密内容,您需要模数和解密(私有)指数对(n,d)。那就是你的私钥。

要使用RSA公钥加密某些内容,请将纯文本视为数字,并将其提高为e模数n的幂:

ciphertext = ( plaintext^e ) mod n

要使用RSA私钥解密某些内容,请将密文视为数字并将其提高到d模数n的幂:

plaintext = ( ciphertext^d ) mod n

要使用openssl生成私钥(d,n),可以使用以下命令:

openssl genrsa -out private.pem 1024

要使用openssl从私钥生成公钥(e,n),可以使用以下命令:

openssl rsa -in private.pem -out public.pem -pubout

要解析上面的openssl命令生成的private.pem私有RSA密钥的内容,请运行以下命令(输出在此处被截断为标签):

openssl rsa -in private.pem -text -noout | less

modulus         - n
privateExponent - d
publicExponent  - e
prime1          - p
prime2          - q
exponent1       - d mod (p-1)
exponent2       - d mod (q-1)
coefficient     - (q^-1) mod p

私钥不应该仅由(n,d)对组成吗?为什么会有6个额外的组件?它包含e(公共指数),因此可以从private.pem私有RSA密钥生成/提取/导出公共RSA密钥。剩下的5个组件在那里可以加快解密过程。事实证明,通过预先计算和存储这5个值,可以将RSA解密速度提高4倍。解密可以在没有这5个组件的情况下工作,但是如果方便的话,可以更快地完成解密。加速算法基于中国剩余定理

是的,private.pem RSA私钥实际上包含所有这8个值;当您运行上一个命令时,它们都不是即时生成的。尝试运行以下命令并比较输出:

# Convert the key from PEM to DER (binary) format
openssl rsa -in private.pem -outform der -out private.der

# Print private.der private key contents as binary stream
xxd -p private.der

# Now compare the output of the above command with output 
# of the earlier openssl command that outputs private key
# components. If you stare at both outputs long enough
# you should be able to confirm that all components are
# indeed lurking somewhere in the binary stream
openssl rsa -in private.pem -text -noout | less

PKCS#1 v1.5建议使用RSA私钥的这种结构作为替代(第二种)表示形式。PKCS#1 v2.0标准从替代表示形式中完全排除了e和d指数。PKCS#1 v2.1v2.2通过可选地包含更多与CRT相关的组件,提出了对替代表示形式的进一步更改。

要查看public.pem公用RSA密钥的内容,请运行以下命令(此处输出被截断为标签):

openssl rsa -in public.pem -text -pubin -noout

Modulus             - n
Exponent (public)   - e

这里没有惊喜。正如承诺的那样,它只是(n,e)对。

现在终于回答了最初的问题:如上所示,使用openssl生成的私有RSA密钥包含公共密钥和私有密钥的组件以及其他一些组件。当您从私钥生成/提取/派生公钥时,openssl将其中两个组件(e,n)复制到一个单独的文件中,该文件成为您的公钥。


您写了“要从私钥生成公钥(d,n)...”。它不是“(e,n)”吗?不过,谢谢您的出色回答!
elactic

您正在将v1.5中的(外部)“语法”与更高版本中的语义进行比较;检查2.0#11.1.2和2.1和2.2#A.1.2,您会看到n,e,d仍然存在。(正如James Polk的回答已经指出的那样。)
dave_thompson_085

1
令人惊讶的解释。谢谢
Francisco Albert

1
似乎公共指数e始终是65537 0x010001。选择公共指数可能是事实,这可能就是为什么在手册页中的原因,几乎所有地方genrsa都解释为to generate the private key。公众很明显。
洗发水

我可以仅从(n,d)计算出(n,e )吗?
Flyq

21

某些人认为,公钥没有存储在PEM文件中。私有密钥文件上存在以下DER结构:

openssl rsa -text-在mykey.pem中

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

所以,有足够的数据来计算公钥(模数和公共指数),这是什么openssl rsa -in mykey.pem -pubout


我看到公用密钥没有存储在那里,尽管可以像私有密钥一样被派生,但是我也看不到私有密钥也存储在那里?但是,如果我找到该pem文件,我会看到它显示了私钥和一些ascii。
barlop

2
私钥也派生,请查看privateExponent字段。您可以通过查看的字段OpenSSL的RSA -text -in mykey.pem
Uxio

2
公钥实际上存储在pem中,因为pem还包含e和d,即公钥。与离散日志算法不同,不能仅根据私钥(d,n)计算rsa公钥。它的存在仅仅是因为rsa规范指示将其与私钥和其他信息一起存储。
Michael Chourdakis '16年

1
是的,这个答案在所有意图和目的上都是错误的。公有指数和模数都在其中,因此公钥肯定存在。除了无需进行任何计算即可轻松检索它的公钥之外,那里就不需要公共指数。
Maarten Bodewes

1
@MaartenBodewes:答案是正确的。引用的内容取自相关的RFC作为PRIVATE密钥存储的值。两个值也/仅用于公共密钥加密不会改变这是私有密钥数据。在过去的两天内,我已经学到了所有这些东西,不是通过提问而是通过查找和阅读相关标准来学习的。我现在了解有关ASN.1,DER,PEM和RSA的全部知识(也许不是全部有关RSA的知识)。
AlastairG

8

首先在此代码中,我们正在创建RSA密钥,它是私有的,但它也具有一对公共密钥,因此,只需执行以下操作即可获取您的实际公共密钥

openssl rsa -in mykey.pem -pubout > mykey.pub

希望您能获得更多信息,请检查此


6

首先,快速回顾一下RSA密钥生成。

  1. 随机选择两个随机大小合适的素数(p和q)。
  2. 将两个素数相乘以产生模数(n)。
  3. 选择一个公共指数(e)。
  4. 用素数和公共指数做一些数学运算以产生私有指数(d)。

公用密钥由模数和公用指数组成。

最小私钥将由模数和私钥指数组成。从已知的模数和私有指数到相应的公共指数,没有从计算上可行的保证方法。

然而:

  1. 实用的私钥格式几乎总是存储大于n和d的数据。
  2. 通常不会随机选择e,而是使用少数几个众所周知的值之一。如果e是众所周知的值之一,并且您知道d,那么很容易通过反复试验找出e。

因此,在大多数实际的RSA实现中,您可以从私钥中获取公钥。在这不可能的情况下,有可能构建基于RSA的密码系统,但这还没有完成。


1
Use the following commands:

1. openssl req -x509 -nodes -days 365 -sha256 -newkey rsa:2048 -keyout mycert.pem -out mycert.pem

Loading 'screen' into random state - done
Generating a 2048 bit RSA private key
.............+++
..................................................................................................................................................................+++
writing new private key to 'mycert.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.

2. If you check there will be a file created by the name : mycert.pem

3. openssl rsa -in mycert.pem -pubout > mykey.txt
writing RSA key

4. If you check the same file location a new public key : mykey.txt will be created.

1
真傻 当您想要的只是密钥对时,无需付出额外的努力来创建无用的证书。对于您想获得证书的其他Q,这可能是答案。
dave_thompson_085
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.