I am learning the basics of SSH protocol. I am confused between the contents of the following 2 files:

  1. ~/.ssh/authorized_keys: Holds a list of authorized public keys for servers. When the client connects to a server, the server authenticates the client by checking its signed public key stored within this file

  2. ~/.ssh/known_hosts: Contains DSA host keys of SSH servers accessed by the user. This file is very important for ensuring that the SSH client is connecting the correct SSH server.

I am not sure what this means. Please help.


The known_hosts file lets the client authenticate the server, to check that it isn't connecting to an impersonator. The authorized_keys file lets the server authenticate the user.

Server authentication

One of the first things that happens when the SSH connection is being established is that the server sends its public key to the client, and proves (thanks to public-key cryptography) to the client that it knows the associated private key. This authenticates the server: if this part of the protocol is successful, the client knows that the server is who it claims it is.

The client may check that the server is a known one, and not some rogue server trying to pass off as the right one. SSH provides only a simple mechanism to verify the server's legitimacy: it remembers servers you've already connected to, in the ~/.ssh/known_hosts file on the client machine (there's also a system-wide file /etc/ssh/known_hosts). The first time you connect to a server, you need to check by some other means that the public key presented by the server is really the public key of the server you wanted to connect to. If you have the public key of the server you're about to connect to, you can add it to ~/.ssh/known_hosts on the client manually.

By the way, known_hosts can contain any type of public key supported by the SSH implementation, not just DSA (also RSA and ECDSA).

Authenticating the server has to be done before you send any confidential data to it. In particular, if the user authentication involves a password, the password must not be sent to an unauthenticated server.

User authentication

The server only lets a remote user log in if that user can prove that they have the right to access that account. Depending on the server's configuration and the user's choice, the user may present one of several forms of credentials (the list below is not exhaustive).

  • The user may present the password for the account that he is trying to log into; the server then verifies that the password is correct.
  • The user may present a public key and prove that he possesses the private key associated with that public key. This is exactly the same method that is used to authenticate the server, but now the user is trying to prove its identity and the server is verifying it. The login attempt is accepted if the user proves that he knows the private key and the public key is in the account's authorization list (~/.ssh/authorized_keys on the server).
  • Another type of method involves delegating part of the work of authenticating the user to the client machine. This happens in controlled environments such as enterprises, when many machines share the same accounts. The server authenticates the client machine by the same mechanism that is used the other way round, then relies on the client to authenticate the user.
  • 11
    thanks this is very helpful. Would it be right to say that known_hosts file is maintained on client whereas authorized_key file is maintained on the server – Ankit Sep 28 '12 at 7:25
  • 1
    @Ankit Yes, that is the case. – Gilles Sep 28 '12 at 14:38
  • I have both files on the server and ssh to it to test it. But the 2 files have different contents. So the keys are different in these files? – Timo Apr 11 '18 at 8:19
  • @Timo The keys are completely unrelated. One is the key of a machine, the other is the key of a user. – Gilles Apr 11 '18 at 14:06

Those two files are both used by SSH but for completely different purposes, which could easily explain your confusion.

Authorized Keys

By default SSH uses user accounts and passwords that are managed by the host OS. (Well, actually managed by PAM but that distinction probably isn't too useful here.) What this means is that when you attempt to connect to SSH with the username 'bob' and some password the SSH server program will ask the OS "I got this guy named 'bob' who's telling me his password is 'wonka'. Can I let him in?" If the answer is yes, then SSH allows you to authenticate and you go on your merry way.

In addition to passwords SSH will also let you use what's called public-key cryptography to identify you. The specific encryption algorithm can vary, but is usually RSA or DSA, or more recently ECDSA. In any case when you set up your keys, using the ssh-keygen program, you create two files. One that is your private key and one that is your public key. The names are fairly self-explanatory. By design the public key can be strewn about like dandelion seeds in the wind without compromising you. The private key should always be kept in the strictest of confidence.

So what you do is place your public key in the authorized_keys file. Then when you attempt to connect to SSH with username 'bob' and your private key it will ask the OS "I got this guy name 'bob', can be be here?" If the answer is yes then SSH will inspect your private key and verify if the public key in the authorized_keys file is its pair. If both answers are yes, then you are allowed in.

Known Hosts

Much like how the authorized_keys file is used to authenticate users the known_hosts file is used to authenticate servers. Whenever SSH is configured on a new server it always generates a public and private key for the server, just like you did for your user. Every time you connect to an SSH server, it shows you its public key, together with a proof that it possesses the corresponding private key. If you do not have its public key, then your computer will ask for it and add it into the known_hosts file. If you have the key, and it matches, then you connect straight away. If the keys do not match, then you get a big nasty warning. This is where things get interesting. The 3 situations that a key mismatch typically happens are:

  1. The key changed on the server. This could be from reinstalling the OS or on some OSes the key gets recreated when updating SSH.
  2. The hostname or IP address you are connecting to used to belong to a different server. This could be address reassignment, DHCP, or something similar.
  3. Malicious man-in-the-middle attack is happening. This is the biggest thing that key checking is trying to protect you from.

In both cases, known_hosts and authorized_keys, the SSH program is using public key cryptography in order to identify either the client or the server.

  • 3
    "Every time you connect to an SSH server it presents its private key in order to prove its identity." I certainly hope not! I assume you meant its public key. If a server presented me, the client, with its private key - it (A) wouldn't work for me to authenticate it and (B) is an indication that the server is so badly configured that I should stop doing business with it immediately. Private keys should only be accessible on the machine of origin by designated users. That's kinda the point. ;-) – underscore_d Sep 22 '15 at 20:33
  • This answer helped me more than the accepted one (: – chaosguru Aug 29 '18 at 9:07
  • If I ssh to a local server (local IP), and then later from the same computer but now remotely connect to the same server (public IP) will it trigger mismatching keys? How can you mitigate this? – deanresin Aug 8 at 3:55

Not true at all.

The known_hosts file contain the fingerprint of the host. It is not the public or private key of the remote host.

It is generated from their key - but it is emphatically NOT the key itself.

If you SFTP to an address that might resolve to several (varying) hosts (load balanced etc) you must add the fingerprints from all the possible end points, or it will work initially and then fail when it is routed to the second (or subsequent) host.

  • 2
    erm look at your known_hosts file and compare it to a host fingerprint when you connect.... That should clear it up a bit. Furthermore, your example would be exactly the same, regardless if it is fingerprints or public keys in the known_hosts file. – Njomsky Feb 16 '15 at 22:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.