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 FILEandbad permissions. Runchmod 600on the file and try again. - You gave it the wrong file.
-yneeds the private key, not the.pubfile. - It is a
.ppkfile. Useputtygen key.ppk -Linstead, 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.