84

I'm having an issue generating a public key that the openssl PEM_read_bio_RSA_PUBKEY() function can consume. I keep getting errors.

Obviously I cannot simply use the ASCII string in the ssh-keygen <>.pub key file as it is in SSH file format or I perhaps SubjectPublicKeyInfo structure.

Here's the key gen code: ssh-keygen -t rsa -b 1024 -C "Test Key"

I found a converter in php on the web which will convert the contents of the public key into a base64 PEM ASCII string format. However the function still doesn't like it.

The Openssl documentation states:

  1. “RSA_PUBKEY() function which process a public key using an EVP_PKEY structure”
  2. “RSA_PUBKEY functions also process an RSA public key using an RSA structure”

How do I get my OpenSSH public key into either format that the OpenSSL function will consume it?

3
  • Figured this out: use the openssl tool only as such:
    – PeteP
    Dec 16, 2011 at 23:17
  • Create Private key: openssl genrsa -out test.priv.key 2048; Output Public key in same format (PEM?): openssl rsa -in test.priv.key -pubout -out test.pub.key
    – PeteP
    Dec 16, 2011 at 23:19
  • Cross-related security.stackexchange.com/questions/32768/… May 31, 2019 at 6:08

6 Answers 6

89

OK!

So I walked into this thinking "Easy, I got this." Turns out there's a whole lot more to it than even I thought.

The first issue is that (according to the man pages for OpenSSL, man 3 pem), OpenSSL is expecting the RSA key to be in PKCS#1 format. Clearly, this isn't what ssh-keygen is working with. You have two options (from searching around).

If you have OpenSSH v. 5.6 or later (I did not on my laptop), you can run this:

ssh-keygen -f key.pub -e -m pem

The longer method of doing this is to break apart your SSH key into its various components (the blog entry I found some of this in accuses OpenSSH of being "proprietary", I prefer to call it "unique") and then use an ASN1 library to swap things around.

Fortunately for you, someone wrote the code to do this:

https://gist.github.com/1024558

7
  • 12
    The ssh-keygen method seems to work on Linux but not Mac OS X.
    – lid
    Mar 16, 2014 at 18:32
  • 3
    Lid, see the note in the answer about SSH version. OS X doesn't ship a recent version of OpenSSH. Run the command ssh -V. Jun 5, 2014 at 15:53
  • 3
    Doesn't work in OpenSSH_6.2p2. Does work in OpenSSH_6.6p1.
    – Old Pro
    Sep 23, 2014 at 22:30
  • -m doesn't work for me ... what is the work around?
    – pstanton
    Jun 14, 2016 at 5:49
  • 2
    Works for me on mac! Sep 11, 2019 at 2:41
34

Assuming you have the SSH private key id_rsa, you can extract the public key from it like so:

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

I realize the OP asked about converting a public key, so this doesn't quite answer the question, however I thought it would be useful to some anyway.

Note also that this command results in a PEM public key format, which is generally what OpenSSL expects. The answer by Brian, on the other hand, results in a file in RSAPublicKey format, which is not the normal format expected by OpenSSL (though later versions can apparently read it via the -RSAPublicKey_in flag). To convert you can do this:

openssl rsa -RSAPublicKey_in -in id_rsa.rsapub.pem -pubout -out id_rsa.pub.pem
4
  • Thanks, the -pubout from the private key did the trick for me. Oct 26, 2016 at 10:26
  • openssl rsa -in id_rsa.pem -pubout -out id_rsa.pub.pem also work (i.e. input is pem format private key). Good answer. Dec 21, 2017 at 10:20
  • 1
    Update: Brian's answer has been corrected to -m pkcs8 which in spite of OpenSSH folks using the wrong name does produce X.509 'PUBKEY'. Also, since OpenSSH 6.5 in 2014-01 if the creator specified 'new format' -o for better security, this method won't work, and since 7.8 in 2018-08 'new format' is now the default, ditto. May 31, 2019 at 6:06
  • 1
    One liners: openssl rsa -RSAPublicKey_in -in <(ssh-keygen -e -m pem -f id_rsa.pub) > id_rsa.pub.pem or ssh-keygen -e -m pem -f id_rsa.pub | openssl rsa -RSAPublicKey_in > id_rsa.pub.pem
    – Bruce
    Mar 6, 2020 at 2:07
30

The format you want is what ssh-keygen calls PKCS8. So the following command will produce the desired output:

ssh-keygen -f key.pub -e -m pkcs8

From the ssh-keygen man page:

-m key_format
         Specify a key format for the -i (import) or -e (export) conversion 
         options.  The supported key formats are: 
         ``RFC4716'' (RFC 4716/SSH2 public or private key), 
         ``PKCS8'' (PEM PKCS8 public key) or 
         ``PEM'' (PEM public key).  
         The default conversion format is ``RFC4716''.
4
  • This one actually works on both Linux and macOS.
    – Jay Taylor
    May 30, 2019 at 19:15
  • to extract the equivalent generated public key from private key in OpenSSL openssl rsa -in key -pubout -out key.pub.openssl.pkcs8
    – Mohannd
    Jun 5, 2019 at 12:01
  • Unsupported conversion format "pksc8"
    – samayo
    Dec 11, 2019 at 1:50
  • @samayo: You misspelled "pkcs8" by swapping the s and the c. Sep 26, 2021 at 12:30
7

Similar to Amal Chaudhuri's method below, this is what worked for me. I needed to create a pem file from the ssh public key I'd generated for my SFTP client (Cyberduck).

openssl rsa -in ~/.ssh/id_rsa -outform pem > id_rsa.pem
3
  • this doesn't actually seem to work. Oct 17, 2014 at 21:51
  • 6
    This ONLY works for private RSA key NOT the public key OP was asking. So wrong answer.
    – Devy
    Jun 11, 2015 at 20:02
  • 3
    Actually, id_rsa already is in the right format, you can check it out by yourself, the resulting id_rsa.pem is 100% identical. Jan 27, 2017 at 4:13
0
ssh-keygen -f path/to/id_rsa.pub -e -m pem > path/to/rsa.pem

Here's what each part of the command does:

-f path/to/id_rsa.pub: Specifies the input file, the path to your existing OpenSSH public key file (id_rsa.pub).

-e -m pem: Specifies the format conversion to PEM.

">" path/to/rsa.pem: Redirects the output to a file named rsa.pem in the specified directory (path/to/).

ssh-keygen -f id_rsa.pub -e -m pem > yourfilename.pem 
-2

Another way to do this from another site. Posting this in case you need another method. Works very well. http://www.chatur.com.np/2011/01/convert-openssh-rsa-key-to-pem-format.html

openssl dsa -in ~/.ssh/id_dsa -outform pem > id_dsa.pem
2
  • That method doesn't seem to actually work.
    – Sean
    Apr 5, 2013 at 18:41
  • 7
    id_rsa is not a public key. Wrong answer. Apr 7, 2015 at 21:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .