Skip to content

/commands/ssh-protocol/get-public-key-from-private-key

ssh-keygen -y -f ~/.ssh/id_ed25519: get the public key from a private key

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
SSH protocol
versions
OpenSSH 7.x – 10.x
os
linux, macos, windows

ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub reads a private key and prints the matching public key in the one-line authorized_keys format. Use it when the .pub file was lost, to check that a .pub file really belongs to a private key, or to get the line to paste into a server's ~/.ssh/authorized_keys. For an encrypted key, ssh-keygen asks for the passphrase first.

Regenerate and compare

bash
ssh-keygen -q -t ed25519 -N '' -C demo@laptop -f id_demo
cp id_demo.pub original.pub && rm id_demo.pub
ssh-keygen -y -f id_demo > id_demo.pub
cmp -s id_demo.pub original.pub && echo "regenerated .pub is identical"
cut -d' ' -f1,3 id_demo.pub
echo "--- encrypted key, wrong passphrase"
ssh-keygen -q -t ed25519 -N 'correct horse' -f locked
ssh-keygen -y -P 'wrong' -f locked; echo "exit $?"
echo "--- right passphrase"
ssh-keygen -y -P 'correct horse' -f locked | cut -d' ' -f1

Output

regenerated .pub is identical
ssh-ed25519 demo@laptop
--- encrypted key, wrong passphrase
Load key "locked": incorrect passphrase supplied to decrypt private key
exit 255
--- right passphrase
ssh-ed25519

The first field is the key type, the second the base64 key, the third the comment. The key line itself is what servers compare, so two files that differ only in the comment still match.

Check that a .pub belongs to a private key

Comparing fingerprints is easier than comparing base64 strings:

bash
ssh-keygen -lf ~/.ssh/id_ed25519.pub
ssh-keygen -y -f ~/.ssh/id_ed25519 | ssh-keygen -lf -

If the two SHA256: fingerprints are equal, the files are a pair. -lf - reads the key from standard input (OpenSSH 7.2 and later).

Variants

CommandResult
ssh-keygen -y -f KEYPublic key in OpenSSH one-line format on standard output.
ssh-keygen -y -f KEY > KEY.pubRecreate a lost .pub file next to the private key.
ssh-keygen -y -P 'phrase' -f KEYNon-interactive, for scripts (the passphrase shows up in the process list).
ssh-keygen -y -f KEY | ssh-keygen -lf -Fingerprint of the public half, to compare with a server or another file.
ssh-keygen -e -f KEY.pubConvert the public key to RFC 4716 format for other SSH implementations.
ssh-keygen -y -f key.pemWorks with PEM or PKCS#8 private keys too, for example a cloud provider key.

Pitfalls

  • A wrong passphrase prints Load key "FILE": incorrect passphrase supplied to decrypt private key and exits with 255.
  • On Linux and macOS, ssh-keygen and ssh refuse private keys readable by other users with UNPROTECTED PRIVATE KEY FILE!; run chmod 600 KEY first.
  • If the server still answers Permission denied (publickey) after you add the regenerated line, the key is fine and the problem is on the server side; see Permission denied (publickey).

FAQ

Can I get the private key back from the public key?

No. The public key is derived from the private key in one direction only. If the private key is lost, generate a new pair and replace the old public key on every server.

Does ssh-keygen -y need the passphrase?

Yes, when the private key is encrypted. It asks for it interactively, or you can pass it with -P in a script, keeping in mind that command-line arguments are visible to other users of the machine.

Why is the comment missing from the regenerated public key?

The comment is stored in the private key file only in the OpenSSH key format. Keys in the older PEM format have no comment, so ssh-keygen -y prints just the type and the key. The comment does not affect authentication.

Sources