关于openssl:使用RSA私钥生成公钥?

Use RSA private key to generate public key?

我不太明白这一点:

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

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

我最初的想法是它们是成对产生的。RSA私钥包含SUM吗?还是公共钥匙?


1
openssl genrsa -out mykey.pem 1024

将实际生成一个公私密钥对。该对存储在生成的mykey.pem文件中。

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

将提取公钥并打印出来。下面是一个链接,指向一个更好地描述这一点的页面。

编辑:检查这里的示例部分。要只输出私钥的公共部分:

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

要获取用于ssh目的的可用公钥,请使用ssh-keygen:

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


正在查找ssh公钥的人…

如果要提取用于OpenSSH的公钥,则需要稍微不同地获取公钥。

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

此公钥格式与OpenSSH兼容。把公钥附加到remote:~/.ssh/authorized_keys上,你就可以走了。

来自SSH-KEYGEN(1)的文件

1
ssh-keygen -y [-f input_keyfile]

-y This option will read a private OpenSSH format file and print an OpenSSH public key to stdout.


在大多数生成RSA私钥(包括openssl)的软件中,私钥表示为pkcs 1 rsa private key对象或其变体:

A.1.2 RSA private key syntax

An RSA private key should be represented with the ASN.1 type
RSAPrivateKey:

1
2
3
4
5
6
7
8
9
10
11
12
  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算法加密某些内容,您需要模和加密(公共)指数对(N,E)。这是你的公钥。要使用RSA算法解密某些内容,您需要模数和解密(私有)指数对(n,d)。那是你的私人钥匙。

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

1
ciphertext = ( plaintext^e ) mod n

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

1
plaintext = ( ciphertext^d ) mod n

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

1
openssl genrsa -out private.pem 1024

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

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

要分析由上述openssl命令生成的private.pem private rsa密钥的内容,请运行以下命令(此处将输出截断为标签):

1
2
3
4
5
6
7
8
9
10
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(public exponent),这样就可以从private.pem private rsa密钥生成/提取/派生public rsa密钥。剩下的5个组件用于加速解密过程。结果表明,通过预计算和存储这5个值,可以将RSA解密速度提高4倍。解密不需要这5个组件就可以工作,但是如果您方便的话,可以更快地完成。加速算法基于中国余数定理。

是的,private.pem rsa private key实际上包含了这8个值中的所有值;当您运行上一个命令时,这些值中没有一个是动态生成的。尝试运行以下命令并比较输出:

1
2
3
4
5
6
7
8
9
10
11
12
# 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.1和v2.2通过选择包含更多与CRT相关的组件,建议对替代表示法进行进一步更改。

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

1
2
3
4
openssl rsa -in public.pem -text -pubin -noout

Modulus             - n
Exponent (public)   - e

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

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


公钥没有像一些人认为的那样存储在PEM文件中。私钥文件上存在以下DER结构:

openssl rsa -text -in mykey.pem

1
2
3
4
5
6
7
8
9
10
11
12
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所做的。


在这段代码中,我们首先创建的是RSA密钥,它是私有的,但它也有一对公钥,所以为了获得您的实际公钥,我们只需执行以下操作

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

希望你能得到更多信息。检查这个。


首先简要回顾一下RSA密钥生成。

  • 随机选取两个适当大小的随机可能素数(P和Q)。
  • 将两个素数相乘,得到模(n)。
  • 选择一个公共指数(e)。
  • 对素数和公共指数做一些数学运算,得到私有指数(d)。
  • 公钥由模和公共指数组成。

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

    然而:

  • 实用的私钥格式几乎总是存储多于N和D的内容。
  • e通常不是随机选取的,而是使用少数已知值中的一个。如果e是众所周知的值之一,而你知道d,那么很容易通过试错法算出e。
  • 因此,在大多数实际的RSA实现中,您可以从私钥中获取公钥。在不可能的情况下,可以构建一个基于RSA的密码系统,但这不是一件容易的事情。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    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.