How to decode private key from PEM and how to extract the Public Key

I am trying to load a private key in PEM file, and then extract the public key portion. Unfortunately I have not had any success with this, and I have not found a crate that can help with this.

After closed and down voted questions on StackOverflow:

I am here to ask for pointers. How may I load a PEM file that contains a private key, and extract the public portion, with the option to even export it as a PEM file?

There's a pem crate.

I'll give this a try now. Hopefully this will be the crate I am looking for...

Not sure if this fits my needs. A quick look at the documentation I can't find how to extract the public key from the private key for instance. :confused:

You'd presumably use parse_many() and compare tags.

Does not look like it. parse_many() returns Pem in pem - Rust and looking through that, it does not provide the functionality needed.

It is interesting that it is this hard to get this done.

I am using RSA, so I even checked the RSA rust crate out rsa - Rust and that also does not seem to have a way to decode keys from pem files!

I'm not sure we are talking about the same thing. Slightly adapting the example found in the documentation, you could just perform a naïve linear search on all returned entries and pick whichever one you need: Rust Explorer

They're almost certainly asking for a library that will do the math on the private key to generate a fresh copy of the public part.

1 Like

Every time I've used PEM, the tools which created the cert created separate files for the public and private parts. I've only had to recover public keys from private keys while developing Blockchain libraries and tools, which have their own (not PEM) formats.

Is there a reason you need to do public key recovery with PEM? Note that ECC is the only widespread algorithm which can do public key recovery, and it's not the only algorithm commonly used with PEM. ECC also requires some extra bits stored with the private key to indicate which of up to 4 solutions is the published public key; I doubt PEM stores those bits.

RSA doesn't support public key recovery. It's not a crate issue; the math to do that just doesn't efficiently exist.

The statement that you can't get the public key from a key file is a bit strong: Can I get a public key from an RSA private key? - Information Security Stack Exchange

But it's not a standard functionality you should expect in a library.

1 Like

Okay, so there are two (actually, three) separate issues here:

  1. Parsing and emitting PEM files with arbitrary content.
    • This is exactly what the pem crate is for.
  2. Mathematically computing (not "extracting from a file") an RSA public key given only the information of the private key.
    • This is impossible (or at least, as strong a problem as breaking RSA and factoring are)
  3. Extracting only the public key from a file that contains information about both the private and the public key, which some systems confusingly just call a "private key".
    • This is possible, but you'll have to parse the internal, possibly DER-encoded ASN.1 structure of the file. In which case, this has borderline nothing to do with PEM.

Which one of these 3 problems are you trying to solve?

3 Likes

hm? no, an RSA private key should store (e, d, p-1, q-1) and you can do (p-1+1) * (q-1+1) to recover N.

Or e = 65537 might be implied in your format and it doesn't need storage.

But the above text is correct: This isn't a PEM problem.

You're adding a requirement to RSA. An RSA implementation only has to store (d, n) for the private key, which isn't enough to calculate e for the public key.

1 Like

Although even then e is typically tiny (I don't think I've seen anything other than 3 or 65537?), so in practice you can still pull it off.

Good point. It is recoverable.

No. d and n are the minimal information necessary for a usable private key.

No 2. And I was able to do this using the openssl crate. The private_key_from_pem and public_key_to_pem methods did the job

Okay, so it's actually #3 (OpenSSL's "private" key files contain information for the private and the public key).

Assuming you meant public_key_from_pem, this sounds like it solves your original question exactly. If that is not the case, could you elaborate what problem it doesn't solve that you still need to address?

No more problems. Using the combination of those two methods, I was able to do what I wanted.

1 Like