The workflow of SSH Protocol Version 1
SSH Protocol works on Layer 5 of the OSI model which is also known as Session Layer. A common mis-conception is that SSH works on Public Key Cryptography and not on Secret Key
A good program that you would want to use for remote login should have the CIA features which are confidentiality, integrity and authentication methods where these three mean the following:
- Confidentiality – The data is private and is encrypted/decrypted.
- Integrity – The data is not tampered/altered between source and destination.
- Authentication – The source and the destination should provide their identity to establish a trust.
SSH has all the above features which make it a very efficient remote login application. SSH protocol has two versions which are version 1 and version 2.
Let’s talk a little bit about confidentiality which comprises of encryption and decryption. Encryption is achieved using cryptography. I might use these terms interchangeably. The two most common cryptography mechanisms being used today are:
- Public Key Cryptography | Asymmetric Cryptography
- Secret Key Cryptography | Symmetric Cryptography
Note – A common mis-conception is that SSH works on Public Key Cryptography and not on Secret Key
The above statement is not completely true. The steps involved in Public Key Encryption are a lot and take a lot of resources therefore most of the protocols use Public Key Encryption to ONLY SHARE THE SECRET KEY USED FOR SECRET KEY CRYPTOGRAPHY. In other words, ASYMMETRIC ENCRYPTION IS ONLY USED TO SHARE THE SECRET KEY, WHICH WILL BE USED FOR SYMMETRIC ENCRYPTION.
Since the connection is initiated by the client, the client authenticates the server first. Once the server has been authenticated, and the client is sure about the identity of the server, a secure symmetric channel is formed between them. This secure channel is then further used for authenticating the client, sharing keys, passwords and other things.
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. 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. At this point, the client will continue if it supports version 2 protocol, otherwise will break the connection.
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”
The server now sends the following information:
a) Server Identity Disclosure
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. It is created during the openssh server installation. If the client is communicating with the server for the first time. The client will get a warning saying:
The authenticity of host '192.168.0.105 (192.168.0.105)' can't be established.
RSA key fingerprint is f7:sdafjlsdjflajsdfowjoejojlo:sd:23:1e:a3:14:s3
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.
Note – 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)
b) Server Key
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)
c) 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.
d) Finally, the server provides all supported encryption, as well as authentication methods.
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.
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
We will only be discussing the two most commonly used methods here. Passwords & public key method of 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 you 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.)
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.
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(id_rsa.pub). Keep in mind that anything that is encrypted with the public key(id_rsa.pub), can only be decrypted with the corresponding private key (which in our case is id_rsa). Now let’s share this id_rsa.pub, 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 id_rsa.pub. Sharing means the content of the file id_rsa.pub, 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 authentications methods supported by the server, the client will select a public key authentication and will also send 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 sent 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.
I have based this blog majorly on this awesome post and have attempted to make it concise.