Use RSA private key to generate public key?

633,046

Solution 1

openssl genrsa -out mykey.pem 1024

will actually produce a public - private key pair. The pair is stored in the generated mykey.pem file.

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

will extract the public key and print that out. Here is a link to a page that describes this better.

EDIT: Check the examples section here. To just output the public part of a private key:

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

To get a usable public key for SSH purposes, use ssh-keygen:

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

Solution 2

People looking for SSH public key...

If you're looking to extract the public key for use with OpenSSH, you will need to get the public key a bit differently

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

This public key format is compatible with OpenSSH. Append the public key to remote:~/.ssh/authorized_keys and you'll be good to go


docs from SSH-KEYGEN(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.

Solution 3

In most software that generates RSA private keys, including OpenSSL's, the private key is represented as a PKCS#1 RSAPrivatekey object or some variant thereof:

A.1.2 RSA private key syntax

An RSA private key should be represented with the ASN.1 type
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
  }

As you can see, this format has a number of fields including the modulus and public exponent and thus is a strict superset of the information in an RSA public key.

Solution 4

My answer below is a bit lengthy, but hopefully it provides some details that are missing in previous answers. I'll start with some related statements and finally answer the initial question.

To encrypt something using RSA algorithm you need modulus and encryption (public) exponent pair (n, e). That's your public key. To decrypt something using RSA algorithm you need modulus and decryption (private) exponent pair (n, d). That's your private key.

To encrypt something using RSA public key you treat your plaintext as a number and raise it to the power of e modulus n:

ciphertext = ( plaintext^e ) mod n

To decrypt something using RSA private key you treat your ciphertext as a number and raise it to the power of d modulus n:

plaintext = ( ciphertext^d ) mod n

To generate private (d,n) key using openssl you can use the following command:

openssl genrsa -out private.pem 1024

To generate public (e,n) key from the private key using openssl you can use the following command:

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

To dissect the contents of the private.pem private RSA key generated by the openssl command above run the following (output truncated to labels here):

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

Shouldn't private key consist of (n, d) pair only? Why are there 6 extra components? It contains e (public exponent) so that public RSA key can be generated/extracted/derived from the private.pem private RSA key. The rest 5 components are there to speed up the decryption process. It turns out that by pre-computing and storing those 5 values it is possible to speed the RSA decryption by the factor of 4. Decryption will work without those 5 components, but it can be done faster if you have them handy. The speeding up algorithm is based on the Chinese Remainder Theorem.

Yes, private.pem RSA private key actually contains all of those 8 values; none of them are generated on the fly when you run the previous command. Try running the following commands and compare output:

# 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

This structure of the RSA private key is recommended by the PKCS#1 v1.5 as an alternative (second) representation. PKCS#1 v2.0 standard excludes e and d exponents from the alternative representation altogether. PKCS#1 v2.1 and v2.2 propose further changes to the alternative representation, by optionally including more CRT-related components.

To see the contents of the public.pem public RSA key run the following (output truncated to labels here):

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

Modulus             - n
Exponent (public)   - e

No surprises here. It's just (n, e) pair, as promised.

Now finally answering the initial question: As was shown above private RSA key generated using openssl contains components of both public and private keys and some more. When you generate/extract/derive public key from the private key, openssl copies two of those components (e,n) into a separate file which becomes your public key.

Solution 5

The Public Key is not stored in the PEM file as some people think. The following DER structure is present on the Private Key File:

openssl rsa -text -in 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
}

So there is enough data to calculate the Public Key (modulus and public exponent), which is what openssl rsa -in mykey.pem -pubout does

Share:
633,046
c2h2
Author by

c2h2

Updated on September 25, 2021

Comments

  • c2h2
    c2h2 over 2 years

    I don't really understand this one:

    According to https://www.madboa.com/geek/openssl/#key-rsa, you can generate a public key from a private key.

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

    My initial thinking was that they are generated in a pair together.

    Does the RSA private key contain the sum? Or the public key?

  • Raam
    Raam about 13 years
    Do you mean that given a private key, its mathematically feasible to generate the public key? Isn't the strength of RSA the fact that its computationally unfeasible to generate one key given the other?
  • President James K. Polk
    President James K. Polk about 13 years
    @Raam: No, the strength of RSA is that it is infeasible to generate the private key from the public. Generate the public form the private is trivial.
  • Jaime Hablutzel
    Jaime Hablutzel about 12 years
    it is confusing how everyone in tutorials everywhere is saying that using the openssl genrsa command you will generate the PRIVATE KEY, because they are forgetting that it is generating the PUBLIC KEY too
  • Ashwin
    Ashwin almost 12 years
    @Raam : What about this command - openssl genrsa -out mykey.key 1024. Does mykey.key contain both the public-private key pair?
  • Raam
    Raam almost 12 years
    @Ashwin, yes mykey.key will have both.
  • Despertar
    Despertar over 11 years
    @jaime can you really blame them? The official documentation says absolutely nothing about a public key. "DESCRIPTION: The genrsa command generates an RSA private key." openssl.org/docs/apps/genrsa.html
  • Jaime Hablutzel
    Jaime Hablutzel over 11 years
    @Despertar you are right, for someone without a good PKI background it can get confusing, but after reading some theory now I now the public key is composed from some parts of the private key, so you only need to generate the private key
  • steveayre
    steveayre about 11 years
    @jaime, That's because it doesn't - genrsa only generates the private key, the public key doesn't get stored. However if you have the private key then you can calculate (derive) the public key from it - which is what the 2nd command above does. It calculates, not extracts, the public key.
  • lynks
    lynks almost 11 years
    @steveayre It was my understanding that the RSA keys were simply the two exponents (e and d in the common literature). Neither one is mathematically private or public, those are labels which are arbitrarily assigned upon creation. They could just as easily be assigned in reverse. Generating one from the other is an equivalent problem. The .pem format contains a whole bunch of information, including both exponents, and so both keys, right?
  • Devy
    Devy over 10 years
    This works like a charm! It generates a format that Github takes! Github doesn't take the PEM format.Previous answer suggested openssl rsa -in key.pem -pubout -out pubkey.pem didn't get accepted as evidently the output of that is a pem format public key. So I got this error: "Key is invalid. It must begin with 'ssh-rsa' or 'ssh-dss'. Check that you're copying the public half of the key". However ssh-keygen -y [-f input_keyfile] generates the correct format that Github takes.
  • Devy
    Devy over 10 years
    Got error "Key is invalid. It must begin with 'ssh-rsa' or 'ssh-dss'. Check that you're copying the public half of the key" on Github taking the output from mykey.pub via openssl rsa -in mykey.pem -pubout > mykey.pub. However @naomik 's suggestion of ssh-keygen -y [-f input_keyfile] worked like a charm!
  • Calmarius
    Calmarius almost 10 years
    @GregS, Why? A key consists of a modulus and an exponent. If the other exponent can be calculated from these two numbers RSA would be cracked easily. So does OpenSSL private key contains more than exponent and modulus?
  • President James K. Polk
    President James K. Polk almost 10 years
    @Calmarius: Who says a key consists of a modulus and exponent? That would be the minimal private key, but usually the private key includes other components like the prime factors. Read the answer for the details.
  • barlop
    barlop over 9 years
    I see the public key isn't stored there, though derivable as is the private key, but I don't see the private key stored there either?! yet if i cat the pem file I see it says private key and some ascii.
  • Uxío
    Uxío over 9 years
    The private key is also derivated, look at the privateExponent field. You can see the fields using openssl rsa -text -in mykey.pem
  • barlop
    barlop over 9 years
    from that it looks a bit like it's not really a private key file, and that it's not deriving the public key from the private key.. but it's deriving the private key from those fields.. or the public key from those fields. However, could it be deriving all of those fields, from the private key? Since if you cat the file, it shows "begin private key" then some ascii then "end private key" and that's it.
  • FractalSpace
    FractalSpace almost 9 years
    @steveayre partially correct. However, there is one subtle difference: you can generate a public key from a given private key, but not the reverse.
  • FractalSpace
    FractalSpace almost 9 years
    @Raam openssl genrsa does not produce a private public key pair. It only generates a private key. A public key is then 'generated' from the given private key using a mathematical relationship. See en.wikipedia.org/wiki/RSA_%28cryptosystem%29
  • Dmytro
    Dmytro almost 8 years
    PEM, PUB, KEY, what do these extensions mean? O.o much confuse.
  • Michael Chourdakis
    Michael Chourdakis over 7 years
    The public key is actually stored in the pem, because the pem also includes e and d, that is, the public key. Unlike discrete log algos, the rsa public key cannot be calculated from merely the private key (d,n). It is there only because the rsa specs indicate to store it with the private key and other info.
  • Admin
    Admin over 7 years
    Your openssl rsa -in key.pem -pubout -out pubkey.pem gives error why ?
  • golem
    golem almost 7 years
    @steveayre is mostly wrong. The public RSA key components (n, e) DO get generated with and are embedded into the private RSA key file created with openssl genrsa command. A separate public key file is not created at the same step though. To extract public key from the private key file into separate public key file you use your openssl rsa -in private.pem -pubout -out public.pem command. When you produce a public key this way, it is extracted from the private key file, not calculated. See my answer below for more details.
  • golem
    golem almost 7 years
    @FractalSpace, you can generate public key from the private key file produced by openssl because it has public key components embedded. If it had only the necessary minimum of (n, d) components, you wouldn't be able to generate the public RSA key from the private one. On the other hand if you know two initial primes (p and q) it is possible to generate public exponent e (and by extension public key) from the private exponent d and private exponent d (and by extension private key) from the public exponent e.
  • Johannes Jasper
    Johannes Jasper almost 7 years
    you wrote "To generate public (d,n) key from the private key...". Shouldn't it be "(e,n)"? Thank you for the great answer, though!
  • Maarten Bodewes
    Maarten Bodewes almost 7 years
    Yep, this answer is in all intent and purposes WRONG. Both the public exponent and the modulus are in there, so the public key is certainly present. There is no need for the public exponent in there other than to easily retrieve the public key for it without any calculations.
  • AlastairG
    AlastairG over 6 years
    @MaartenBodewes: The answer is correct. What is quoted is taken from the relevant RFC as the values stored for a PRIVATE key. That two of the values are also/only used for public key encryption does not change that this is the private key data. I have learnt all this stuff over the last two days, not by asking questions but by looking up and reading the relevant standard. I now understand all about ASN.1, DER, PEM, and RSA (well perhaps not ALL about RSA).
  • dave_thompson_085
    dave_thompson_085 over 6 years
    You're comparing (external) 'syntax' in v1.5 to semantics in later versions; check 2.0 #11.1.2 and 2.1 and 2.2 #A.1.2 and you'll see n,e,d still present. (As James Polk's answer already noted.)
  • dave_thompson_085
    dave_thompson_085 over 6 years
    This is silly; there's no need to go to extra effort to create a useless certificate when all you want it is a keypair. For some other Q where you want a cert this could be an answer.
  • croraf
    croraf over 6 years
    Even though I don't know much about cryptography I agree with @golem. And other likes above on wrong answers are confusing. And I think lynks questions should be confirmed. Both of keys can be used as private, so generating one from other would make RSA useless?
  • Michael Curtis
    Michael Curtis over 6 years
    Regarding confusing documentation: man openssl doesn't explain generating the public key, but man rsa does explain the -pubout option.
  • fabmlk
    fabmlk over 6 years
    cryptographic-wise, the public key is indeed in the private .pem: openssl rsa -text < mykey.pem. In that sense @jaime's upvoted comment is confusing. But certficate-wise, the public pem is indeed derived from the private pem.
  • shampoo
    shampoo about 6 years
    It seems that the public exponent e is always 65537 0x010001. It's probably a defacto for choosing the public exponent and this is probably why in the man page, and almost every where genrsa is explained as to generate the private key. The public one is kinda obvious.
  • Maarten Bodewes
    Maarten Bodewes about 6 years
    @AlastairG If you learned that the public exponent is part of the private key then you didn't understand the course. It is only available as convenience and/or to perform verification (which can be part of a defense against side channel attacks). Note that the accepted answer identifies the file as the key pair. The last 2 days, sheesh, what about my last 17 years?
  • Maarten Bodewes
    Maarten Bodewes about 6 years
    @JamesKPolk That's not necessarily true. If the public exponent is large (i.e. has the same properties as the private exponent) then the public key may be impossible to reconstruct. Most libraries won't support this but the RSA cryptosystem certainly doesn't require you to reconstruct the public key from the private key.
  • Maarten Bodewes
    Maarten Bodewes about 6 years
    @AlastairG But my main issue was that the public key quite definitely is stored in there, and the answer says it is not. The public key consists of the modulus and the public exponent, and they are clearly present. No calculation needs to be performed.
  • President James K. Polk
    President James K. Polk about 6 years
    @MaartenBodewes: What's not true? Don't forget to also look at the question when considering the context of the answer.
  • AlastairG
    AlastairG about 6 years
    @Maarten The public key is not present as a public key, i.e. as a separate entity. To say the public key is there is like saying that a shopping basket containing eggs, sugar, flour, and various other ingredients, contains a cake. I agree that you don't need to calculate the values, but you can't call the answer wrong (in bold caps) simply because the auther used the word "calculate" rather than, say, "generate".
  • Flyq
    Flyq over 4 years
    Can I compute out the (n, e) only from (n, d)?
  • flow2k
    flow2k over 3 years
    Seems like the EDIT openssl rsa -in key.pem -pubout -out pubkey.pem just repeats latter part of the original answer.