How does ssh public key authentication work?

  • My basic understanding is this:

    • The (connected to) server's sshd uses the public key to encrypt some message
    • The client's ssh or ssh-agent decrypts it and sends something back (the message's checksum? its signature?)
    • The server's sshd verifies that this is consistent with the message to authenticate the user

    But what are the details? What is the "some message", what does ssh(-agent) send back? Would doing this with the same original message over and over again always yield the same communication?

    Can this authentication process be replayed via bash tools if ssh-agent is used? E.g. the public keys that ssh-agent provides can be obtained via ssh-add -L, what about the rest of the process? Or would that require manually connecting to the $SSH_AUTH_SOCK unix socket and some low-level communication?


    Related: Thomas' Server-Bob dialogue here, though that suggests the client just signs some random data that will then be checked against all public keys of the server user's authenticated_keys. This illustration on the other hand claims the message is encrypted to the previously determined user's public key (not the one for the ssh encryption) and the client outputs the checksum which also depends on some random session ID. Which one is correct? Or do both only tell part of the actually more complex story?

    "The (connected to) server's sshd uses the public key to encrypt some message" - which public key are you referring to?

  • The particulars of the authentication depend on the protocol version and the type of key. In all cases, there is always a challenge, with some randomness to avoid replay attacks. When the user key is of type DSA, a true digital signature is necessarily involved, since DSA is a signature-only algorithm. The article you link to shows something which assumes that the user key can do asymmetric encryption; I guess this is something that SSHv1 did (in SSHv1, all keys were RSA, and RSA can do asymmetric encryption). For the current (SSHv2) protocol, public-key based client authentication is specified in RFC 4252, section 7.

    The core concept remains the same: the client proves its control of the private key by performing an operation which requires knowledge of that key, but such that the "inverse" operation can be done with the public key which is located in the .ssh/authorized_keys on the server.

    The journey is its own reward. You learn a good deal more by digging through RFC than by reading a clean, pre-digested answer on a Q&A site.

    True, that one was at least short enough :-7 But what about the remainder of my question, can I use some bash-script to send some arbitrary data back to the forwarded `ssh-agent` and have it sign that?

    You're right about the difference between v1 and v2, see third paragraph here

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM