552

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?

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
c2h2
  • 11,911
  • 13
  • 48
  • 60
  • 3
    To every one using rsa and openssl and wanting to encrypt a large file like 5 Kbyte. please remeber that the public key should be proportional or bigger in size to what you want to encrypt otherwise you will get a "file to big to be encrypted fault." I summarize that you generate a rather large and serious private key and from that make your private keys so that you have a lot of data to work with. I told whom i know in openssl about the flaw, and that they should just make it loop on it self otherwise you will use a lot of time figuring out why it complain about the size. – Kent Hansen May 29 '13 at 12:22
  • 14
    The problem Kent Hansen describes is due to using RSA directly on plaintext data, which should never be done in any case for security reasons. Instead use a well-analysed hybrid encryption scheme such as RSA-KEM (https://tools.ietf.org/html/rfc5990#appendix-A), with an authenticated symmetric encryption scheme such as encrypt-then-HMAC applied to the data. – Daira Hopwood Dec 26 '13 at 23:31
  • This may help: http://jason4zhu.blogspot.jp/2014/10/generate-public-key-from-private-key.html – Judking Oct 28 '14 at 07:37
  • 1
    related: https://serverfault.com/questions/52285/create-a-public-ssh-key-from-the-private-key – David Cary Mar 01 '19 at 20:45
  • @SteffenUllrich's answer in this link explains why: https://security.stackexchange.com/questions/172274/can-i-get-a-public-key-from-an-rsa-private-key – bearzyj Jun 19 '19 at 11:10

10 Answers10

818
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
Jay Taylor
  • 13,185
  • 11
  • 60
  • 85
Raam
  • 10,296
  • 3
  • 26
  • 27
  • 67
    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 – Jaime Hablutzel May 16 '12 at 22:17
  • @Raam : What about this command - openssl genrsa -out mykey.key 1024. Does mykey.key contain both the public-private key pair? – Ashwin May 29 '12 at 06:39
  • @Ashwin, yes mykey.key will have both. – Raam May 29 '12 at 06:42
  • 26
    @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." http://www.openssl.org/docs/apps/genrsa.html – Despertar Sep 29 '12 at 23:46
  • @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 – Jaime Hablutzel Oct 03 '12 at 16:21
  • 155
    @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. – steveayre Feb 27 '13 at 14:59
  • 17
    @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? – lynks Jul 17 '13 at 16:47
  • 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! – Devy Nov 26 '13 at 20:35
  • 3
    @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 Jun 12 '15 at 13:19
  • 3
    @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 https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29 – FractalSpace Jun 12 '15 at 13:23
  • PEM, PUB, KEY, what do these extensions mean? O.o much confuse. – Dmytro Jun 30 '16 at 04:36
  • Your openssl rsa -in key.pem -pubout -out pubkey.pem gives error why ? –  Sep 03 '16 at 20:13
  • 21
    @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 Jun 04 '17 at 17:27
  • 7
    @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`. – golem Jun 04 '17 at 18:18
  • 1
    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? – croraf Oct 26 '17 at 08:57
  • Regarding confusing documentation: man openssl doesn't explain generating the public key, but man rsa does explain the -pubout option. – Michael Curtis Jan 09 '18 at 16:46
  • 1
    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. – fabmlk Feb 01 '18 at 09:29
  • Seems like the EDIT `openssl rsa -in key.pem -pubout -out pubkey.pem` just repeats latter part of the original answer. – flow2k Jan 15 '21 at 09:22
  • I understand it that way: the `.pem` file contains all the coefficients to generate both the public and the private key (see golem's answer). Therefore, it might not exactly be _the_ private key (of a key pair), but it should obviously kept likewise privately and securely because it can _generate_ one. – Ingmar Jun 09 '23 at 16:28
352

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.

Mulan
  • 129,518
  • 31
  • 228
  • 259
  • 3
    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 Nov 26 '13 at 20:31
91

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.

Community
  • 1
  • 1
President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • 1
    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? – Raam Mar 09 '11 at 13:00
  • 41
    @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. – President James K. Polk Mar 10 '11 at 00:20
  • 1
    @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? – Calmarius Jul 11 '14 at 14:47
  • 1
    @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. – President James K. Polk Jul 11 '14 at 22:24
  • 2
    @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 Apr 12 '18 at 22:39
  • @MaartenBodewes: What's not true? Don't forget to also look at the question when considering the context of the answer. – President James K. Polk Apr 12 '18 at 23:28
62

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.

Community
  • 1
  • 1
golem
  • 1,820
  • 1
  • 20
  • 25
  • 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! – Johannes Jasper Jul 21 '17 at 07:13
  • 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 Oct 22 '17 at 08:05
  • 2
    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. – shampoo Feb 20 '18 at 18:40
  • 1
    Can I compute out the (n, e) **only** from (n, d)? – Flyq Jan 17 '20 at 06:56
20

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

Uxío
  • 1,333
  • 11
  • 12
  • 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. – barlop Oct 08 '14 at 10:22
  • 2
    The private key is also derivated, look at the privateExponent field. You can see the fields using openssl rsa -text -in mykey.pem – Uxío Oct 08 '14 at 17:17
  • 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. – barlop Oct 08 '14 at 18:22
  • 2
    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. – Michael Chourdakis Aug 20 '16 at 21:10
  • 1
    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*. – Maarten Bodewes Aug 09 '17 at 16:08
  • 1
    @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). – AlastairG Oct 17 '17 at 11:57
  • 1
    @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 Apr 12 '18 at 22:35
  • @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. – Maarten Bodewes Apr 12 '18 at 22:43
  • 1
    @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". – AlastairG Apr 30 '18 at 14:04
8

Firstly a quick recap on RSA key generation.

  1. Randomly pick two random probable primes of the appropriate size (p and q).
  2. Multiply the two primes together to produce the modulus (n).
  3. Pick a public exponent (e).
  4. Do some math with the primes and the public exponent to produce the private exponent (d).

The public key consists of the modulus and the public exponent.

A minimal private key would consist of the modulus and the private exponent. There is no computationally feasible surefire way to go from a known modulus and private exponent to the corresponding public exponent.

However:

  1. Practical private key formats nearly always store more than n and d.
  2. e is normally not picked randomly, one of a handful of well-known values is used. If e is one of the well-known values and you know d then it would be easy to figure out e by trial and error.

So in most practical RSA implementations you can get the public key from the private key. It would be possible to build a RSA based cryptosystem where this was not possible, but it is not the done thing.

plugwash
  • 9,724
  • 2
  • 38
  • 51
7

here in this code first we are creating RSA key which is private but it has pair of its public key as well so to get your actual public key we simply do this

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

hope you get it for more info check this

Rdx
  • 195
  • 4
  • 11
5

The file called "private key" includes much more information than the private key alone, it includes all the data (primes, modulus, exponents, etc..) needed to generate private/public key pair.

And it is very easy to see see this information:

openssl genrsa -out private.pem 1024   #generate private key file
openssl rsa -in private.pem -text      #view info in the private key file
openssl rsa -in private.pem -pubout -out public.pem  #extract public key to file
openssl rsa -in public.pem -pubin -text  #view info in the public key file

You will see that that private key file includes the primes with all other information while the public file includes only the modulus and the public exponent.

Mendi Barel
  • 3,350
  • 1
  • 23
  • 24
0

Seems to be a common feature of the prevalent asymmetric cryptography; the generation of public/private keys involves generating the private key, which contains the key pair:

openssl genrsa -out mykey.pem 1024

Then publish the public key:

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

or

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

DSA & EC crypto keys have same feature: eg.

openssl genpkey -algorithm ed25519 -out pvt.pem

Then

openssl pkey -in pvt.pem -pubout > public.pem

or

openssl ec -in ecprivkey.pem -pubout -out ecpubkey.pem

The public component is involved in decryption, and keeping it as part of the private key makes decryption faster; it can be removed from the private key and calculated when needed (for decryption), as an alternative or complement to encrypting or protecting the private key with a password/key/phrase. eg.

openssl pkey -in key.pem -des3 -out keyout.pem

or

openssl ec -aes-128-cbc -in pk8file.pem -out tradfile.pem

You can replace the first argument "aes-128-cbc" with any other valid openssl cipher name

Zimba
  • 2,854
  • 18
  • 26
-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 has been created.

bfontaine
  • 18,169
  • 13
  • 73
  • 107
Ankit Jain
  • 2,230
  • 1
  • 18
  • 25
  • 1
    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. – dave_thompson_085 Oct 22 '17 at 08:08