1

I have created an open-ssh keypair using ssh-keygen with the defaults, and encrypted the private key with a passphrase. I already know how to derive the public-key from the private-key using ssh-keygen -y, for which I will need to enter the passphrase protecting the private-key. But, is it possible to extract the public-key from this file without the passphrase?

2
  • when you say "this file", do you mean a file that contains only the encrypted private key or a file that contains both the encrypted private and the public key?
    – user284677
    Commented Mar 2, 2023 at 20:49
  • By "this file", I meant the file generated by ssh-keygen whose name by default is id_rsa. As per @dave_thompson_085, it is no longer just a private-key anymore, but something more closely resembling PuTTY's format; it "contains the public key in unencrypted form even when the private key is encrypted". Also, right now, the public-key given out by ssh-keygen -e is not being accepted as valid by the ssh-keygen -l (get key fingerprint). So, we can't compare the public-keys given by the two ('-y' and '-e') options, using this way, for now.
    – Sami
    Commented Mar 4, 2023 at 5:42

3 Answers 3

2

Depends on version.

In OpenSSH below 7.8, ssh-keygen by default generates an RSA key(pair) and writes it in (what OpenSSH now calls) 'old' format which is OpenSSL's 'traditional' aka 'legacy' format which is encrypted (if at all) using PEM-level encryption, and extracting any details including the public key requires decryption using the passphrase.

In 7.8 up, ssh-keygen by default writes in OpenSSH 'new' format, which contains the public key in unencrypted form even when the private key is encrypted. But you'll need to write your own code to do this; 'normal' ssh-keygen -y still needs the passphrase because it uses routines that read the whole keypair even when that isn't really needed.

Versions 6.5 up write 'new' format if you specify -o (which is unnecessary and ignored in 7.8 up), and also do so by default if you generate ed25519 because there was (and still is) no OpenSSL 'traditional' format for that algorithm.

See the file PROTOCOL.key in any recent source distribution or on github, or code in several libraries that read this format, for example I find Jsch in Java to be easy to read and understand.

As Spyros says, private-key operations -- namely sign (used for SSH) or decrypt (not normally used in SSH, but could still be done by other software with an SSH key) -- (still) require decryption with the passphrase.

0
2

Apparently, this is possible: ssh-keygen -ef id_rsa outputs the public-key without needing us to give the password protecting the private-key.

The public-key generated this way (-ef) matches the original generated public-key:

# Get the value of public-key using the 'y' flag:
ssh-keygen -yf id_rsa > id_rsa--y.pub
cat id_rsa--y.pub | cut -d' ' -f 2 | tr -d '\n' > id_rsa--y-value.pub

# Get the value of public-key using the 'e' flag:
sed -n 3,10p <(ssh-keygen -ef id_rsa) | tr -d '\n' > id_rsa--e-value.pub

diff id_rsa--y-value.pub id_rsa--e-value.pub
# diff returns nothing, indicating a perfect match
1

Clarification: the answer is about extracting/producing a public key from a file that only contains an encrypted private key. Extracting a public key from a file that contains both the (encrypted) private key and the (plaintext) public key is covered in other answers.

--- Original answer ---
No, it is not possible - given that we're not talking about breaking the encryption in any way, that is.

The purpose of encryption is to protect the private key so it is inaccessible and cannot be used to produce/decrypt/sign accordingly with the respective public key.

You must log in to answer this question.

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