47

I have server which I am accessing via SSH. I only allow the authentication to be made with private key. Normally when I login via PuTTY, I am first asked for username and then asked for passphrase for the key. Out of curiosity I have created new private key, which should be invalid for my user and I also have put passphrase on it. To my surprise once I provided the user name the key attempted to login with to my server was refused before I have been asked for the passphrase.

I am wondering how can SSH server know that the private key is incorrect if the passphrase for it haven't been provided yet?

vakus
  • 3,743
  • 3
  • 20
  • 32

2 Answers2

83

While you've encrypted the private key, the public key is still readable. SSH authentication with the "publickey" method works by having the client send each potential public key to the server, then the server responds telling the client which key is allowed. If one of the keys is allowed, then the client must decrypt the private key to sign a message, proving ownership of the private key.

In your experiment, the server responded saying that none of the provided keys was allowed for your username, so there was no need to decrypt a private key, authentication had already failed.

AndrolGenhald
  • 15,436
  • 5
  • 45
  • 50
  • 2
    Theortically a naughty client could send public keys for which it does not have the corresponding private key, correct? – PyRulez Jan 10 '19 at 06:18
  • 12
    @PyRulez Yes, but then the server will ask the client to prove it has the corresponding private key. Which it can't. – SomeoneSomewhereSupportsMonica Jan 10 '19 at 06:36
  • 10
    Could that information be abused, like testing with all public keys from github to find the owner of a server? – Johannes Kuhn Jan 10 '19 at 10:23
  • 2
    @JohannesKuhn You have to supply both username and public key. So you must already know that the username and key go together. – Ben Jan 10 '19 at 14:21
  • further, @JohannesKuhn, that would depend on the third party using the same public keys for managing servers as they do their github accounts. – JCRM Jan 10 '19 at 15:33
  • 2
    If pubkey auth for root is used (which, contrary to a lot of misinformation, is not a bad practice, and generally has much smaller attack surface and lower risk than having su or sudo installed) then root would be a natural candidate to test. – R.. GitHub STOP HELPING ICE Jan 10 '19 at 19:34
  • @JohannesKuhn That's an interesting idea. As far as I recall OpenSSH by default enforce a limit of at most 10 public keys attempted per connection. However by default it doesn't limit the number of connection attempts a client can make, so the 10 public keys limit is more likely to hit legitimate users than to prevent the search you suggest. The most straightforward fix would cause a major nuisance to anybody using keys which require confirmation on every usage. – kasperd Jan 10 '19 at 23:26
  • @JCRM Public keys are usually not considered to be sensitive, and for that reason it isn't generally considered bad practice to use the same key to log in to more than one location. If you do have multiple keys chances are you have `ssh` configured to try them all on each server where you log in. That means a list of all your public keys could easily leak, and it also means it's not practical to have more than 10 key pairs, as OpenSSH by default doesn't allow you to try more than 10. – kasperd Jan 10 '19 at 23:33
  • 1
    @R.. I agree with that. There was a [question](https://security.stackexchange.com/q/66894/47143) about that in the past. – kasperd Jan 10 '19 at 23:34
  • no, I have ssh configured to use the correct keys for the hosts I'm connecting to @kasperd. I share keys between hosts within the security domain but not otherwise. Just as I wouldn't share usernames between them. – JCRM Jan 11 '19 at 20:08
  • @JCRM I use kasperd as my username on every system that will allow me to. I don't see a need to choose a different username on every system that I use. – kasperd Jan 11 '19 at 20:32
  • and that is your choice to make @kasperd – JCRM Jan 11 '19 at 22:08
14

During connection client will sent successively fingerprint of all availables keys to server.

When server signal to client a valid key found, client will use them, then ask for passphrase if needed.

Try to run ssh with debug option:

ssh -o LogLevel=DEBUG3 user@dest

look for fingerprint with

ssh-keygen -l -f .ssh/id_rsa

For checking authorized_keys, line by line:

while read line;do
    ssh-keygen -l -f <(echo "$line")
  done <.ssh/authorized_keys 
  • 6
    Note that instead of `-o LogLevel=DEBUG3` (lots of typing), `-vvv` (three times verbose) should also work. – Luc Jan 09 '19 at 16:44