How to recover an SSH public key from the private key

Run ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub. This reads the private key and prints the matching public key, so a lost .pub file can always be rebuilt. If the key has a passphrase you need to type it. The opposite is not possible: you cannot get a private key from a public one.

Updated . Commands run with OpenSSH 10.0 on Debian 13, with ed25519 and RSA keys, with and without a passphrase.

The command

ssh-keygen -y -f ~/.ssh/id_ed25519
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINH9eelf0P7eT5ue6SualUXFrh1c9p3Maaem93iZtC2Q you@laptop

This prints the key to the screen. To put it back in its file, send the output there:

ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub

The same command works for a .pem key downloaded from a cloud provider, such as an AWS key pair: ssh-keygen -y -f key.pem.

To put the key back on a server, see how authorized_keys works.

What can go wrong

  • You forgot the passphrase. You get Load key "id_ed25519": incorrect passphrase supplied to decrypt private key. There is no way around this without the passphrase. Make a new key.
  • The file is readable by others. You get UNPROTECTED PRIVATE KEY FILE and bad permissions. Run chmod 600 on the file and try again.
  • You gave it the wrong file. -y needs the private key, not the .pub file.
  • It is a .ppk file. Use puttygen key.ppk -L instead, or convert it first.

The comment may be missing

The new OpenSSH format stores the comment inside the private key, so it comes back in the output. A key in the old format, whose first line is BEGIN RSA PRIVATE KEY, has none, and you get only the type and the key. That works just as well. Add a comment at the end of the line by hand if you want one.

Check that a .pub file matches a private key

ssh-keygen -lf is not a reliable check for this. Given a private key with a .pub file beside it, it reads the .pub file, so it shows the wrong fingerprint if the two do not belong together. We confirmed this with a mismatched pair. Compare the real keys instead:

diff <(ssh-keygen -y -f ~/.ssh/id_ed25519 | cut -d' ' -f1,2) <(cut -d' ' -f1,2 ~/.ssh/id_ed25519.pub) && echo same

This works in bash and zsh. It prints same when they match and shows the difference when they do not. The cut leaves the comment out of the comparison.

Questions

Can I get the private key from the public key?

No. The public key is made from the private key, and the math does not work backwards. If the private key is lost, generate a new pair.

Why does ssh-keygen -y ask for a passphrase?

The private key is encrypted with it, and ssh-keygen has to decrypt the key to compute the public half. Without the passphrase there is no way to get it.

Does the comment at the end of the .pub line matter?

No. It is only a label, for example you@laptop. Servers ignore it, so a public key without one works the same.

Sources

More in Keys and login

All guides