1

I generated a public/private key pair on my client machine. They are in ~/.ssh as id_rsa and id_rsa.pub. I added the public key to the host machine's authorized_keys file, and now I can successfully SSH without needing to type in a password.

Now, I moved my public key out of that folder mv ~/.ssh/id_rsa.pub ~/, and tried to SSH into the host machine again, expecting it to fail (since the public key is missing), but it still works! How come? How is it finding the public key if it's not in the ~/.ssh directory (I tried moving it to different places besides the home folder too, and it still connects without password authentication successfully).

4 Answers 4

3

Make sure your keys are not cached by ssh-agent.

Get list of cached keys:

ssh-add -l

Remove all cached keys:

ssh-add -D
2

With public key cryptography, you give out the public key and keep the private key.. private. When something wants to send something to you, they use the public key to encrypt it, and you use the private key to decrypt it. Once you've given out the public key, you don't need it to decrypt messages.

I do not know the details of how ssh uses those keys, but when using the -v option, I see:

$ ssh -vvv vm
...
debug1: identity file /Users/username/.ssh/id_rsa type 0
...
debug1: Offering public key: /Users/username/.ssh/id_rsa RSA SHA256:...
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 60
debug1: Server accepts key: /Users/username/.ssh/id_rsa RSA SHA256:/...

Given that, my guess is that it's using the private key to get the public key, then sending the public key to the remote host.

If you want to make is so that that configuration no longer works, you'd need to [re]move the private key ( ~/.ssh/id_rsa).

4
  • I see, but when the client SSH's into the host, it doesn't specify which public key it is using? And the server just checks all of the public keys in authorized_keys to see if any of them can decrypt the client's signature?
    – WalksB
    Nov 11, 2020 at 2:44
  • 1
    @ZaidGharaybeh I edited my answer. I don't know all the details, so this is my best guess. Nov 11, 2020 at 2:59
  • Very strange, it seems to be sending a hash of the private key instead of the public key to the server. But then the question is how could it get the public key from that?
    – WalksB
    Nov 11, 2020 at 3:12
  • Is it possible for you to provide the server side sshd logs? Nov 11, 2020 at 4:45
2

You said that the remote still has the public key (in ~/.ssh/authorized_keys). And the local still has the private key (~/.ssh/id_rsa).

That is how.


And yes (to comment on other answer) the protocol just tries all available keys, until it gets in.

And the sending of hashes, is just a way to find the key quicker. The remote will hash all its public keys, compare hashes, and use the key that matches. The public key is derivable from the private key (file).

debug1: Offering public key: /Users/username/.ssh/id_rsa RSA SHA256 suggests that the client is deriving the public key hash from the private key file. So ether the public-key is in there, or it is possible to derive the public-key from the private-key (depending on the key type).

7
  • But it seems that the client is sending a hash of it's private, not public key. How could that be used to match the public keys in authorized_keys file on the host?
    – WalksB
    Nov 11, 2020 at 15:03
  • How do you know that it is the hash of the private key? Nov 11, 2020 at 17:44
  • In the other answer, the verbose log: debug1: Offering public key: /Users/username/.ssh/id_rsa RSA SHA256 seems to suggest that (id_rsa is the private key).
    – WalksB
    Nov 11, 2020 at 18:09
  • I guess it could be deriving the public key from that private key before hashing it and sending it over. In that case I guess the client SSH module technically has no use for the public key file and it's only there for the user's convenience.
    – WalksB
    Nov 11, 2020 at 18:14
  • 1
    Yes I was about to say some of that, and agree with it all. "it could be deriving the public key from that private key file before hashing it and sending it over. In that case the client SSH module has no use for the public key file and it's only there for the user's convenience." Nov 11, 2020 at 18:16
0

and tried to SSH into the host machine again, expecting it to fail (since the public key is missing), but it still works! How come?

Once you have sent your public key to the remote server (and the remote server has stored your public key in its authorized_keys file), you don't need your public key file anymore. All that you need to authenticate is your private key.

Of course, it's good practice to keep the public key file. But since a RSA private key contains the public key, you can always extract the public key file from the private key file.

For detail, this is the content of a RSA private key:

-----BEGIN RSA PRIVATE KEY-----
RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}
-----END RSA PRIVATE KEY-----

and this is the content of a RSA public key:

-----BEGIN RSA PUBLIC KEY-----
RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}
-----END RSA PUBLIC KEY-----   

(Source: RFC 3447.)

You must log in to answer this question.

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