Secure Shell: How Does SSH Work

Sarath Pillai's picture
SSH Working Explained

Taking remote shell, for carrying out different tasks is a norm, if you have multiple server machine's in your infrastructure. Different protocols and tools were made to accomplish this task of taking a remote shell. Although the tools made during the initial days were capable enough to carry out necessary shell related tasks, there were different design concerns, that resulted in advancements and new tools to accomplish this task.

In this tutorial guide, we will be discussing one such tool, that was designed to eliminate the flaws in previous remote shell programs. Our topic of interest for this tutorial is none other than the Secure Sell, better known as SSH.

The key characteristics that makes a remote login program an efficient one is pointed out in the below list.

  • The first and the foremost is the privacy of the communication. This means the connection, which provides a remote shell login, must be encrypted to prevent eavesdropping.
  • There must be a mechanism to check whether the data send by either party is not altered, or tampered with. In short, integrity check is a must.
  • Identity of both the server and the client must be provided to each other, to establish a proper authentication.

A wonderful thing about the Secure Shell (SSH), is the fact that, it incorporates all the above mentioned characteristics, in addition to some unique features of its own.

Encryption and authentication mechanisms provided by SSH enhances security to a greater extent, because mostly the communication occurs through a medium, which is unsecured(The Internet). This is majorly due to the fact that, ssh was made to replace some insecure remote login programs like rlogin,telnet etc.

SSH provides multiple mechanisms for authenticating the server and the client. Two of the commonly used authentication mechanism are password based, and key based authentication. Although password based authentication is also secure, its advisable to use key based authentication instead. As i mentioned before, there are some added features apart from the secure authentication and data encryption provided by ssh. Some of the well known features of SSH are mentioned below.

  • SSH Tunneling
  • TCP port forwarding

We will not be discussing the above mentioned features of SSH in this tutorial, instead will be discussing how an SSH connection from a server to a client work. We will be discussing the complete workflow of an SSH connection in detail. Iterations in protocols to improve the overall working, is a norm. SSH protocol also has different iterations and among them the most widely used versions are SSH version 1 and SSH version 2.

The current default and recommended version of SSH is SSH protocol Version 2. We will be beginning by discussing both these versions separately and will be ending with a comparison of both these two versions of SSH, along with its workflow.

When we discuss encryption and data security, there are two types of primarily used cryptographic systems. One is Public Key cryptography(or sometimes called as asymmetric cryptography) & the other is Secret key cryptography (or sometimes called as symmetric cryptography)Most of the modern day security system's use these two types, in multiple ways to ensure security in communication. I have two article's that discuss tools related to symmetric and asymmetric encryption.

The above tutorial's does not discuss cryptography, but it does describe its application in real life. We will be including a few articles related to cryptography in the coming days (I know its quite difficult to discuss cryptography details, but will surely give it an attempt.laugh)

Workflow of Secure Shell(SSH) Protocol Version 1

The major confusion, that's widely found among industry people, is that "SSH works on Public key encryption and not on Secret Key encryption". I would like to take this opportunity to clear this confusion here. Asymmetric encryption has a lot of overhead involved, and is a little bit time consuming to decrypt data using it.

Due to which most of the protocol employs Public key cryptography(asymmetric encryption), only to share the secret key used for symmetric encryption, which will be used as a primary encryption mechanism for the entire data communication in that session. To make things clear "Asymmetric encryption is only used to share the secret key, which will be used for symmetric encryption"

So if you think logically, the first step, that needs to be taken while establishing an SSH connection, is to make a secure channel between the server and the client.

First the client authenticates the server, because client is the one that initiates the connection. After the server is authenticated, and the client is sure about the identity of the server, a secure symmetric channel is formed between them.

This secure channel will be used for authenticating the client,sharing keys,passwords,and other things. For understanding how this works, let's go through a step by step process.



Step 1

A connection is always initiated by the client to the server. So the first step is to establish a TCP connection to port 22 on the server. Let's see what we get when we connect to port 22 on the server.

[root@slashroot1 ~]# telnet 22

Connected to (
Escape character is '^]'.

The client gets two valuable information from the above connection. One is the Protocol version supported by the server. Second is the ssh server package version(which is not necessary. In fact you should not reveal this message to the client)

At this point, the client will continue if it supports version 2 protocol, otherwise will break the connection.

Step 2

As soon as the client decides whether it should continue, based on the protocol version shown by the server, server and client will now switch to a "Binary Packet Protocol"

This protocol contains a packet length of 32 bits(This length is excluding the length field, and message authentication field), padding 

Step 3:

The server will now send some of the critical information to the client. This information will be playing a major role in the current session of the login.

The information send by the server are as follows.

1. The server will disclose its identity to the client. This identity is a rsa public key of the server. This key is mostly stored in the below location on a server(for this example, i will be working on a centos 5 machine). It is created during the openssh server installation.

[root@slashroot1 ssh]# pwd
[root@slashroot1 ssh]# cat
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxlwxaB4wKrFHGsqUYEzYtTIJWjgul8ML+bnnJIg0HER1wnW2QitRqDzw6f9cr3WKvwqAQh/Sf4bM0LqUAXZre+J6oiLY7X8V6NtEA8nHO1qryueNe44rI6HYunZ3yo4UAXUZqxhjer+tA8OCD6DLRfXOWIMsBUBXJuB+yl1/qGH2J0Kjrnpj17N0mPMqGmMb8+9EjV1Rs1aSDriIWjDsJIDd8fz4gRoelB5mFsEQ7rD+m/RNWxbAhkBoNcFadRg30LqhCtGYQsWADv0p4THCDVZxB3u9VSWK9qZRgF7LbGRdgiVgJjGDPqCO3cWlnQzxcZ9VdvKy+em1RB9BJ++kuw==

If the client is communicating with the server for the first time. The client will get a warning on his screen which will be something like the below.

[root@slashroot1 ~]# ssh
The authenticity of host ' (' can't be established.
RSA key fingerprint is c7:14:f4:85:5f:52:cb:f9:53:56:9d:b3:0c:1e:a3:1f.
Are you sure you want to continue connecting (yes/no)?

The client will get the above warning only when he connects for the first time. After the first connection, this host identity key will be saved in a known_hosts file so that, in future you will not get a warning while connecting to this server.

The thing to understand here is that, the above key is a host identity, and not a user identity. Any client connecting to that server will get that same host-key as a server identity, so that if you connect to another machine, instead of this you will be warned(because the client does not have the identity in its known_host file)

2. The second information provided by the server to the client is the server key. This server key is a key exchanged from server to the client. This method is not used in ssh version 2, which will be discussed later.

This key is also regenerated each and every hour according to the default configuration. Its default size is 768 bits. You can see this in the ssh server configuration file (/etc/ssh/sshd_conf)

# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h
#ServerKeyBits 768


8 random bytes which are also called checkbytes. It is necessary for the client to send these bytes in its reply to the server, during its next reply.

4. Finally the server provides all supported encryption, as well as authentication methods.


Step 4:

According to the list of encryption algorithms supported by the server, the client simply creates a random symmetric key and sends that symmetric key to the server.

This symmetric key will be used to encrypt as well as decrypt the whole communication during this session.

The client takes an additional care while sending this session key(symmetric key for this session) to the server, by doing a double encryption. The first encryption is done by the server host key(which was shared by the server during step 3), and the second encryption is done by the server key(which will keep on changing every one hour.)

This double encryption increases the security, because even if somebody has the host private key of the server (/etc/ssh/ssh_host_rsa_key), he will not be able to decrypt the message, because its still encrypted by the server key, which keeps on changing on an hourly basis.

Along with this double encrypted session key, the client will also send the selected algorithm from the list of supported algorithm given by the server during step 3.

Step 4:

According to the list of encryption algorithms supported by the server, the client simply creates a random symmetric key and sends that symmetric key to the server.

This symmetric key will be used to encrypt as well as decrypt the whole communication during this session.

The client takes an additional care while sending this session key(symmetric key for this session) to the server, by doing a double encryption. The first encryption is done by the server host key(which was shared by the server during step 3), and the second encryption is done by the server key(which will keep on changing every one hour.)

This double encryption increases the security, because even if somebody has the host private key of the server (/etc/ssh/ssh_host_rsa_key), he will not be able to decrypt the message, because its still encrypted by the server key, which keeps on changing on an hourly basis.

Along with this double encrypted session key, the client will also send the selected algorithm from the list of supported algorithm given by the server during step 3.


Step 5:

If you notice, the client has still not authenticated the server. It only has the identity of the server, which was given by the server in the form of server host key.

In order to authenticate the server, the client needs to be sure, that the server was able to decrypt the session key send during step 4. So after sending the session key(which is double encrypted with server key and server host key), the client waits for a confirmation message from the server.

The confirmation from the server must be encrypted with the symmetric session key, which the client send. This step of waiting for a confirmation message is very important for the client, because the client has no other way to verify whether the server host key send, was from the intended server.

Once the client receives a confirmation from the server, both of them can now start the communication with this symmetric encryption key.

But till now only the server is authenticated. The client is yet to be authenticated by the server.


Client Authentication methods supported by SSH

Now the complete communication will be in a symmetric encrypted form, with the help of the session key.

The client authentication happens over this encrypted channel. There are multiple methods that can be used to authenticate the client. Some of them are mentioned below.

  • Public Key

  • Rhosts

  • Password

  • Kerberos

Related : Kerberos and its Working

We will only be discussing the two most commonly used methods here. Passwords & public key method of authentication.

Password authentication

Password based authentication is simple, and is the most commonly used authentication methods in ssh. It is exactly the same as you log in to a local user using the correct password. The remote server on getting the passwords, logs in the user, based on the server's native password authentication mechanism.

Note the fact that the password transmitted by the client to the server is encrypted through the session symmetric key(which only the server and the client knows)

Public Key Authentication

The second authentication method is public key authentication method. Public key authentication in secure shell is the strongest authentication methods, that can be used to authenticate the client.

For this authentication to work, the client first needs to create an RSA public and private key. Which can be done by a command called ssh-keygen. Always keep in mind, that this key generation is only used for authenticating the client, and not used for encrypting the complete session. Encryption of the complete ssh session is already established by a symmetric session key which was previously shared by the client and the server.

Let's see what happens in this public key authentication. We will first need to create two keys(One private and one public). This public key will be given to all those server's where your require authentication. So a client that needs log-in to multiple servers using public key, needs to distribute his key to those multiple servers first. Any data encrypted with that public key, can only be decrypted with the corresponding private key(which is only with the original client.)


[root@slashroot1 ~]# cd .ssh/
[root@slashroot1 .ssh]# ll -a
total 16
drwx------ 2 root root 4096 Feb 25 14:19 .
drwxr-x--- 9 root root 4096 Feb 25 09:58 ..
-rw-r--r-- 1 root root    0 Feb 25 14:08 known_hosts
[root@slashroot1 .ssh]#

The above shown directory of .ssh (which is a directory that contains the user specific ssh details. Its inside the home directory of the user.).

As of now the directory only has one file called known_hosts. This is the file which will contain the complete list of server host keys line by line. We have previously seen that when a user connects to an ssh server for the first time, the user will get a warning of the server host key(because the client does not have the entry of the server host key in the file, which proves the server identity).

After the first connection the server host key is saved in the file known_hosts, so that when you connect again you will not get a warning(this warning is very much helpful, because it will let you know if you are logging into an attacker's machine instead of the original server).

This will be the location(~/.ssh), where the keys for public key authentication will be saved. Lets create our keys for this authentication.

[root@slashroot1 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/
The key fingerprint is:
[root@slashroot1 ~]#

If you see clearly the above command, has created two files in the .ssh directory. One is the private key (id_rsa) which will by default have a permission of 600, and the other is the public key, which will be shared to the server(

Keep in mind that anything that is encrypted with the public key(, can only be decrypted with the corresponding private key (which in our case is id_rsa)

Now let's share this, with the server. The server will keep this public key inside its list of authorized hosts. Sharing this public key does not mean sharing the file Sharing means the content of the file, must be there in the file authorized_keys on the server. This authorized hosts file is also located in the directory .ssh inside the home directory of the target user.

Let's get back to the point where we stopped at step 5.

From the list of authentication method's supported by the server, the client will select a public key authentication and will also send the the details about the cryptography used for this public key authentication.

The server on receiving the public key authentication request, will first generate a random 256 bit string as a challenge for the client, and encrypt it with the client public key, which is inside the authorized_keys file. 

The client on receiving the challenge, will decrypt it with the private key(id_rsa). The client will not send the challenge string as it is. But will combine that string with the session key(which was previously negotiated and is being used for symmetric encryption.) And will generate a md5 hash value. This hash value is send to the server. The server on receiving the hash, will regenerate it(because the server also has both the random string as well as the session key), and if it matches the hash send by the client, the client authentication succeeds.

Now let's get inside SSH protocol version 2.


SSH Protocol Version 2

SSH protocol version 2 is the default protocol used these days. This is due to some major advancements in version 2 compared to version 1. The workflow of the ssh login is almost same as that of version 1, however there are some major changes done in the protocol level. Some of these changes include improved encryption standards, Public key certification, much better message authentication codes, reassignment of session key etc.

If you are using centos/rhel 5 like me, most of you might be using openssh version 4.3 or higher. These ssh client's, by default selects ssh protocol version 2 for login, and it will fallback to version 1 if the server does not support version 2.

Multiple functions like key exchange, authentication, encryption were all part of a single protocol in version 1, due to which it is sometimes called as monolithic. SSH version 2 implements these different functions in different protocol(which combines together to make protocol version 2). Let's see these different internal protocol's inside ssh version 2.

  • Transport Layer Protocol
  • Connection protocol
  • Authentication Protocol

​The above three protocol's inside ssh version 2 is defined in seperate RFC's. 

SSH version 1 is very much limited in its support for wide range of algorithms that can be used for session key exchange, message authentication codes, compression algorithms etc. SSH 2 gives pretty good number of choices for the client to select from. SSH version 2 even has a space for adding your own custom algorithm. 

During our discussion regarding session key (which is the symmetric key used for encrypting the complete session ), we saw that the client after selecting one algorithm from the list of supported by the server, generates a symmetric key and sends it to the server with double encryption(first encryption with the server host key and then with the server key, which keeps on changing every hour). In ssh version 2, there is no concept of server key. Instead it the server provides with the list of supported key exchange methods, from which the client selects one. As of now ssh version 2 works on diffie-hellmangroup1-sha1 for exchanging keys. I will recommend reading the below article of Wikipedia, to get an idea about diffie-hellmangroup1-sha1.

Read: diffie-hellman key exchange method

The basic idea behind this change is that no single party(client or the server), should decide the session key. All the supported key exchange algorithm that will be added in the future, will consist this property(nieigther server nor the client can dictate the session key)

So there is no concept of server key (which is altered every hour) in ssh version 2.  

The second major change in SSH version 2 is the inclusion of a concept called as certificate authority(CA), who will sign the public key's used in the communication. This is exactly the same method used in SSL. However this is never implemented in real world as of now. But the protocol has already a room made for this. 

Message authentication code's are used in any secure communication to verify the integrity of the message. Even SSH version 1 uses a message authentication code called as CRC-32(Cyclic Redundancy Check). CRC although does check alteration in data, but is not considered best when security is a major concern. SSH 2 uses advanced encryption standard based MAC. Some of the supported ssh 2 message authentication codes are as below.

  1. hmac-md5
  2. hmac-sha1
  3. ​hmac-ripemd160

Rekeying of session key

SSH includes an added functionality called as rekying of the session key. What happens is, previously in ssh version 1, only one session key was used for the entire session. These days, almost all activities are carried out by ssh session. I myself login to a remote server, and leave that session as it is for weeks together, to continue from where i left.

In such login ssh session's its better to change the session key without breaking the session. That's a feature in ssh version 2. 

let's now have a summary of the differences between ssh version 1 and ssh version 2

  • Diffie-Hellman key is used instead of the server key for sharing the session key in version 2 protocol
  • No Rhosts support in ssh 2
  • SSH protocol version 1 only allows negotiation of the symmetric encryption algorithm, all other things are hard corded(mac, compression etc)
  • SSH 2 supports certificates for public keys used
  • SSH 2 server can dictate the client to use multiple authentication methods in a single session to succeed. However ssh version 1 only supports one method per session
  • SSH version 2 allows the change of session key periodically.

Hope the above article was helpful in understanding the workflow of ssh. And the differences between two version's of SSH.



Rate this article: 
Average: 4.1 (783 votes)


I was using ssh for long , but never knew what goes behind the scene. I thought of understanding , but most tutorials give private-public key authentication, but didn't give an insight about how the protocol would work. This is very nice article that helped me understand the complete picture. Kudos to you .

Sarath Pillai's picture

Hi kumar swamy,

Thanks for your comment man.!
And yeah welcome to slashroot.


Can u please explain the ssh2 in detail as explained for ssh1

Can u please explain the ssh2 in detail as explained for ssh1

Sarath Pillai's picture

Hi Pradeep,

Thanks for your comment and welcome to slashroot, I will surely write an article explaining ssh version 2..


Great article.

I use ssh daily minimum 20-30 times, but didn't explored in deep. Very good Article :).


Nice one

Good article!

In public key authentication, how does sshd server know which public key (from authorized_keys file) to use to encrypt random 256 bit string?

authorized_keys file does not contain information like client hostname.

Thanks for the article Op, was a good refresher.

good question Michal, you may have already found your answer, but here it is for the benefits of other reading this... From what I have read the client actually sends the fingerprint (md5 hash) of the pub key it wishes to authenticate with to the server. The server checks the authorized_keys file of the account that the client is attempting to log into for that fingerprint. If a public key matching the fingerprint is found in the file, the server generates a random number and uses the client's public key to encrypt the same and rest of the process follows as documented in this blog post.

Here is the ssh client log snippet of the exchange, however, it may seem from the log line below that the client actually presents the entire pub key and not a finger-print (if some one can confirm that, would be nice):

debug1: Offering RSA public key: /home/jigs/.ssh/id_rsa

debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/jigs/.ssh/id_rsa
debug3: send_pubkey_test
debug2: we sent a publickey packet, wait for reply
debug1: Server accepts key: pkalg ssh-rsa blen 277
debug2: input_userauth_pk_ok: fp xx:xx:5f:59:f1:29:d6:d9:7f:13:d8:d7:xx:xx [MD5]
debug3: sign_and_send_pubkey: RSA xx:xx:5f:59:f1:29:d6:d9:7f:13:d8:d7:xx:xx [MD5]
debug1: read PEM private key done: type RSA
debug1: Authentication succeeded (publickey).
Authenticated to H0neyp0t ([10.x.x.x]:22).
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0

easy understood

Nice tutorial..

I have take print this tutorial thanks to all..

you say that we should instruct the SSH daemon to suppress the version printout as anyone can gain knowledge about how to exploit the running version. Simple question: Which argument in sshd_config is it?

Sarath Pillai's picture

Hi Jordan,

As i said in the article, the version details shown by the server is used by the clients while establishing the connection. However being that said, you can disable that by recompiling the ssh source code by removing that stuff altogether.

This type of security is widely discussed and some agree and some disagree(because its security through obscurity), because apart from the version details revealed by the server, there are other methods as well that can be used to detect the version.

The official openssh page says not to remove the ssh version revealed, because of some old clients still under use(which can cause instabilities.). You can methods to recompile without that banner stuff online(however disabling the operating system details revealed by ssh is quite simple by modifying sshd_config)

Many Thanks

Excellent compilation in step-by-step manner.

Predefined glossary of terms like Server,client, session, user, host etc would be immensely helpful to avoid any assumptions that reader has to make here.


good article.........

Hi Sarath,

Your work really helped me a lot, Please continue posting like this about concepts and background details. I always believe "GOOD START" to reach "exponential heights". and I recommend all my students start here at ur blog to get clear picture. After that they will be intuitive and self learners to expand their knowledge.

And if possible please include this link about diffie-hellman algorithm, I read this it really simple to understand.

This link have a pdf, You can save this. Published by


Hi Sarath,

step # 4 is mentioned twice which creates confusion to understood.. rest good article to understand SSH flow..

very good article

Very nicely explained the protocol.

I would like to read more such article

Brothers, your efforts are priceless and immensely appreciated. I always believe in fundamentals and behind the scene actions ,however i never got this far with any available explanation about a protocol at a understandable level.

Like others said, for first time readers it could be bit hard to decipher , otherwise its a phenomenal theory.

Please continue to write up and also let me know if i can contribute in anyway to keep this mission ON.....

thanks once again.

Thank you very much indeed

It really good tutorial for SSH. Nothing more than this. All the best

Good tutorial on SSH..Really appreciate your efforts

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Type the characters you see in this picture. (verify using audio)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.