// Tutorial //

Understanding the SSH Encryption and Connection Process

Published on October 22, 2014 · Updated on March 31, 2022
Default avatar
By Justin Ellingwood
Developer and author at DigitalOcean.
Understanding the SSH Encryption and Connection Process

Introduction

SSH, or secure shell, is a secure protocol and the most common way of safely administering remote servers. Using a number of encryption technologies, SSH provides a mechanism for establishing a cryptographically secured connection between two parties, authenticating each side to the other, and passing commands and output back and forth.

In this guide, we will be examining the underlying encryption techniques that SSH employs and the methods it uses to establish secure connections. This information can be useful for understanding the various layers of encryption and the different steps needed to form a connection and authenticate both parties.

Understanding Symmetric Encryption, Asymmetric Encryption, and Hashes

In order to secure the transmission of information, SSH employs a number of different types of data manipulation techniques at various points in the transaction. These include forms of symmetrical encryption, asymmetrical encryption, and hashing.

Symmetrical Encryption

The relationship of the components that encrypt and decrypt data determines whether an encryption scheme is symmetrical or asymmetrical.

Symmetrical encryption is a type of encryption where one key can be used to encrypt messages to the opposite party, and also to decrypt the messages received from the other participant. This means that anyone who holds the key can encrypt and decrypt messages to anyone else holding the key.

This type of encryption scheme is often called “shared secret” encryption, or “secret key” encryption. There is typically only a single key that is used for all operations or a pair of keys where the relationship is discoverable and it’s trivial to derive the opposite key.

Symmetric keys are used by SSH in order to encrypt the entire connection. Contrary to what some users assume, public/private asymmetrical key pairs that can be created are only used for authentication, not encrypting the connection. The symmetrical encryption allows even password authentication to be protected against snooping.

The client and server both contribute toward establishing this key, and the resulting secret is never known to outside parties. The secret key is created through a process known as a key exchange algorithm. This exchange results in the server and client both arriving at the same key independently by sharing certain pieces of public data and manipulating them with certain secret data. This process is explained in greater detail later on.

The symmetrical encryption key created by this procedure is session-based and constitutes the actual encryption for the data sent between server and client. Once this is established, the rest of the data must be encrypted with this shared secret. This is done prior to authenticating a client.

SSH can be configured to use a variety of different symmetrical cipher systems, including Advanced Encryption Standard (AES), Blowfish, 3DES, CAST128, and Arcfour. The server and client can both decide on a list of their supported ciphers, ordered by preference. The first option from the client’s list that is available on the server is used as the cipher algorithm in both directions.

On Ubuntu 20.04, both the client and the server are defaulted like the following:

  • chacha20-poly1305@openssh.com
  • aes128-ctr
  • aes192-ctr
  • aes256-ctr
  • aes128-gcm@openssh.com
  • aes256-gcm@openssh.com

This means that if two Ubuntu 20.04 machines are connecting to each other (without overriding the default ciphers through configuration options), they will always default to using the chacha20-poly1305@openssh.com cipher to encrypt their connection.

Asymmetrical Encryption

Asymmetrical encryption is different from symmetrical encryption because to send data in a single direction, two associated keys are needed. One of these keys is known as the private key, while the other is called the public key.

The public key can be freely shared with any party. It is associated with its paired key, but the private key cannot be derived from the public key. The mathematical relationship between the public key and the private key allows the public key to encrypt messages that can only be decrypted by the private key. This is a one-way ability, meaning that the public key has no ability to decrypt the messages it writes, nor can it decrypt anything the private key may send it.

The private key should be kept entirely secret and should never be shared with another party. This is a key requirement for the public key paradigm to work. The private key is the only component capable of decrypting messages that were encrypted using the associated public key. By virtue of this fact, any entity capable of decrypting these messages has demonstrated that they are in control of the private key.

SSH uses asymmetric encryption in a few different places. During the initial key exchange process used to set up the symmetrical encryption (used to encrypt the session), asymmetrical encryption is used. In this stage, both parties produce temporary key pairs and exchange the public key in order to produce the shared secret that will be used for symmetrical encryption.

The more well-discussed use of asymmetrical encryption with SSH comes from SSH key-based authentication. SSH key pairs can be used to authenticate a client to a server. The client creates a key pair and then uploads the public key to any remote server it wishes to access. This is placed in a file called authorized_keys within the ~/.ssh directory in the user account’s home directory on the remote server.

After the symmetrical encryption is established to secure communications between the server and client, the client must authenticate to be allowed access. The server can use the public key in this file to encrypt a challenge message to the client. If the client can prove that it was able to decrypt this message, it has demonstrated that it owns the associated private key. Then the server can set up the environment for the client.

Hashing

Another form of data manipulation that SSH takes advantage of is cryptographic hashing. Cryptographic hash functions are methods of creating a succinct “signature” or summary of a set of information. Their main distinguishing attributes are that they are never meant to be reversed, they are virtually impossible to influence predictably, and they are practically unique.

Using the same hashing function and message should produce the same hash; modifying any portion of the data should produce an entirely different hash. A user should not be able to produce the original message from a given hash, but they should be able to tell if a given message produced a given hash.

Given these properties, hashes are mainly used for data integrity purposes and to verify the authenticity of communication. The main use in SSH is with HMAC, or hash-based message authentication codes. These are used to ensure the message text that’s received is intact and unmodified.

As part of the symmetrical encryption negotiation outlined previously, a message authentication code (MAC) algorithm is selected. The algorithm is chosen by working through the client’s list of acceptable MAC choices. The first one on this list that the server supports will be used.

Each message sent after the encryption is negotiated must contain a MAC so that the other party can verify the packet integrity. The MAC is calculated from the symmetrical shared secret, the packet sequence number of the message, and the actual message content.

The MAC itself is sent outside of the symmetrically encrypted area as the final part of the packet. Researchers generally recommend this method of encrypting the data first and then calculating the MAC.

Understanding How SSH Works

You probably already have a basic understanding of how SSH works. The SSH protocol employs a client-server model to authenticate two parties and encrypt the data between them.

The server component listens on a designated port for connections. It is responsible for negotiating the secure connection, authenticating the connecting party, and spawning the correct environment if the credentials are accepted.

The client is responsible for beginning the initial transmission control protocol (TCP) handshake with the server, negotiating the secure connection, verifying that the server’s identity matches previously recorded information, and providing credentials to authenticate.

An SSH session is established in two separate stages. The first is to agree upon and establish encryption to protect future communication. The second stage is to authenticate the user and discover whether access to the server should be granted.

Negotiating Encryption for the Session

When a TCP connection is made by a client, the server responds with the protocol versions it supports. If the client can match one of the acceptable protocol versions, the connection continues. The server also provides its public host key, which the client can use to check whether this was the intended host.

At this point, both parties negotiate a session key using a version of something called the Diffie-Hellman algorithm. This algorithm (and its variants) make it possible for each party to combine their own private data with public data from the other system to arrive at an identical secret session key.

The session key will be used to encrypt the entire session. The public and private key pairs used for this part of the procedure are completely separate from the SSH keys used to authenticate a client to the server.

The basis of this procedure for classic Diffie-Hellman are:

  • Both parties agree on a large prime number, which will serve as a seed value.
  • Both parties agree on an encryption generator (typically AES), which will be used to manipulate the values in a predefined way.
  • Independently, each party comes up with another prime number which is kept secret from the other party. This number is used as the private key for this interaction (different from the private SSH key used for authentication).
  • The generated private key, the encryption generator, and the shared prime number are used to generate a public key that is derived from the private key, but which can be shared with the other party.
  • Both participants then exchange their generated public keys.
  • The receiving entity uses their own private key, the other party’s public key, and the original shared prime number to compute a shared secret key. Although this is independently computed by each party, using opposite private and public keys, it will result in the same shared secret key.
  • The shared secret is then used to encrypt all communication that follows.

This process allows each party to equally participate in generating the shared secret, which does not allow one end to control the secret. It also accomplishes the task of generating an identical shared secret without ever having to send that information over insecure channels. The shared secret encryption that is used for the rest of the connection is called binary packet protocol.

The generated secret is a symmetric key, meaning that the same key used to encrypt a message can be used to decrypt it on the other side. The purpose of this is to wrap all further communication in an encrypted tunnel that cannot be deciphered by outsiders.

After the session encryption is established, the user authentication stage begins.

Authenticating the User’s Access to the Server

The next step involves authenticating the user and deciding on access. There are a few methods that can be used for authentication, based on what the server accepts.

The general method is password authentication, which is when the server prompts the client for the password of the account they are attempting to log in with. The password is sent through the negotiated encryption, so it is secure from outside parties.

Even though the password will be encrypted, this method is not generally recommended due to the limitations on the complexity of the password. Automated scripts can break passwords of normal lengths very easily compared to other authentication methods.

The most popular and recommended alternative is the use of SSH key pairs. SSH key pairs are asymmetric keys, meaning that the two associated keys serve different functions.

The public key is used to encrypt data that can only be decrypted with the private key. The public key can be freely shared, because, although it can encrypt for the private key, there is no method of deriving the private key from the public key.

Authentication using SSH key pairs begins after the symmetric encryption has been established as described in the previous section. The procedure happens as follows:

  • The client begins by sending an ID for the key pair it would like 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 the key ID.
  • If a public key with a matching ID is found in the file, the server generates a random number and uses the public key to encrypt the number.
  • The server sends the client this encrypted message.
  • If the client actually has the associated private key, it will be able to decrypt the message using that key, revealing the original number.
  • The client combines the decrypted number with the shared session key that is being used to encrypt the communication, and calculates the MD5 hash of this value. MD5 is a message-digest algorithm that uses the hash function to generate a 128-bit hash value.
  • The client then sends this MD5 hash back to the server as an answer to the encrypted number message.
  • The server uses the same shared session key and the original number that it sent to the client to calculate the MD5 value on its own. It compares its own calculation to the one that the client sent back. If these two values match, it proves that the client was in possession of the private key and the client is authenticated.

In sum, the asymmetry of the keys allows the server to encrypt messages to the client using the public key. The client can then prove that it holds the private key by decrypting the message correctly. The two types of encryption that are used (symmetric shared secret and asymmetric public/private keys) are each able to leverage their specific strengths in this model.

Conclusion

Learning about the connection negotiation steps and the layers of encryption at work in SSH can help you better understand what is happening when you log in to a remote server. Now you can recognize the relationship between various components and algorithms, and understand how all of these pieces fit together. To learn more about SSH, check out the following guides:


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
10 Comments

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Thank you for putting this together - the complete overview is very useful and (mostly) well written :-)

Let me point out an error regarding asymmetric encryption: “This is a one-way ability, meaning that the public key has no ability to decrypt the messages it writes, nor can it decrypt anything the private key may send it.”

The first part is correct: You cannot use any of those two keys to decrypt a message encrypted with the same key.

The second part is wrong: You can use either of those keys to decrypt a message encrypted with the other one.

Another correction: hashing is not “a form of encryption” at all.

Excellent explanation! Very well written and informative. I use SSH regularly and I’m the kind of guy that always wants to know the detailed inner workings of how things behave. Thank you very much.

Fantastic explanation, keep up the great work! :D

Very nice article, this is really well-written. Helped me understand the distinction between the various cryptographic techniques that go into securing SSH.

I was hoping for some clarification on asymmetric keys. You use the public key to encrypt and the private key to decrypt. But can the opposite happen. Can you encrypt using the private key and decrypt it with the public key using the same key pair for both scenarios.

Thanks for the article. I tried matching the steps described with the verbose log of ssh. Let me know if anything is wrong:

# start program and read configuration
OpenSSH_8.1p1, LibreSSL 2.7.3
debug1: Reading configuration data /Users/user/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 47: Applying options for *

# establish tcp connection
debug1: Connecting to 123.123.123.123 [123.123.123.123] port 22.
debug1: Connection established.

# locate private key (NOT YET SENT)
debug1: identity file /Users/user/.ssh/private_key type -1
debug1: identity file /Users/user/.ssh/private_key-cert type -1

# match ssh protocol (ssh-2.0)
debug1: Local version string SSH-2.0-OpenSSH_8.1
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.4
debug1: match: OpenSSH_7.4 pat OpenSSH_7.0*,OpenSSH_7.1*,OpenSSH_7.2*,OpenSSH_7.3*,OpenSSH_7.4*,OpenSSH_7.5*,OpenSSH_7.6*,OpenSSH_7.7* compat 0x04000002

# set user name (is this sent to the server or not yet?)
debug1: Authenticating to 123.123.123.123:22 as 'ec2-user'

## Negotiating Encryption for the Session
# 1. Both parties agree on a large prime number, which will serve as a seed value.
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received

# 2. Both parties agree on an encryption generator (typically AES), which will be used to manipulate the values in a predefined way.
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ecdsa-sha2-nistp256
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none

# 3. Independently, each party comes up with another prime number which is kept secret from the other party.
#    This number is used as the private key for this interaction (different than the private SSH key used for authentication).
# 4. The generated private key, the encryption generator, and the shared prime number are used to generate a public key that is derived from the private key,
#    but which can be shared with the other party.
# 5. Both participants then exchange their generated public keys.
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:long-fingerprint-of-the-server-key
debug1: Host '123.123.123.123' is known and matches the ECDSA host key.
debug1: Found key in /Users/user/.ssh/known_hosts:131

# 6. The receiving entity uses their own private key, the other party’s public key, and the original shared prime number to compute a shared secret key.
#    Although this is independently computed by each party, using opposite private and public keys, it will result in the same shared secret key.
debug1: rekey out after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey in after 134217728 blocks


## Authenticating the User’s Access to the Server
# 1. The client begins by sending an ID for the key pair it would like to authenticate with to the server.
# 2. The server check’s the authorized_keys file of the account that the client is attempting to log into for the key ID.
# 3. If a public key with matching ID is found in the file, the server generates a random number and uses the public key to encrypt the number.
debug1: Will attempt key: /Users/user/.ssh/private_key  explicit
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<rsa-sha2-256,rsa-sha2-512>

# 4. The server sends the client this encrypted message.
debug1: SSH2_MSG_SERVICE_ACCEPT received

# 5. If the client actually has the associated private key, it will be able to decrypt the message using that key, revealing the original number.
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic
debug1: Next authentication method: publickey

# 6. The client combines the decrypted number with the shared session key that is being used to encrypt the communication, and calculates the MD5 hash of this value.
# 7. The client then sends this MD5 hash back to the server as an answer to the encrypted number message.
debug1: Trying private key: /Users/user/.ssh/private_key

# 8. The server uses the same shared session key and the original number that it sent to the client to calculate the MD5 value on its own.
#    It compares its own calculation to the one that the client sent back.
#    If these two values match, it proves that the client was in possession of the private key and the client is authenticated.
debug1: Authentication succeeded (publickey).

# establish tty session
Authenticated to 123.123.123.123 ([123.123.123.123]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
debug1: Sending env LC_CTYPE = UTF-8
Last login: Mon Nov 22 05:22:23 2021 from public-host-name.com

@jellingwood

Would you please fix this sentence in Bold? The public key can be freely shared with any party. It is associated with its paired key, but the private key cannot be derived from the public key. The mathematical relationship between the public key and the private key allows the public key to encrypt messages that can only be decrypted by the private key. This is a one-way ability, meaning that the public key has no ability to decrypt the messages it writes, nor can it decrypt anything the private key may send it.

I would like to know the no of RTTs happening during the ssh connection , how is it minimized over the years? lets assume we are only using ssh keys.

It’s very detailed article. Can you please add some information related to certificates based authentication?

What are the Sources or References for gathering this information? is it RFCs?

en castellano, mi propia traducción libre de la nota.

Comprendiendo la encriptación SSH y el proceso de conexión

Introducción

SSH (acrónimo de Secure SHell) es un protocolo de seguridad, además de ser la más común de las formas seguras de administrar conexiones a servidores remotos. Mediante el uso de tecnologías de encriptación, SSH brinda un mecanismo para establecer una conexión criptográfica segura entre dos partes, verificando la identidad de cada una y compartiendo métodos de envío y recepción de datos.

En otros artículos tratamos cómo configurar accesos basados en SSH, como conectarse usando SSH, además de otros consejos y trucos de SSH.

En este artículo trataremos las técnicas ocultas de encriptación y los métodos para establecer conexiones seguras que utiliza SSH. Esta información será útil para entender las diversas capas de encriptación y los diferentes pasos necesarios para lograr una conexión y autenticación entre dos partes.

Encriptación simétrica, asimétrica y uso de hash

Con el fin de asegurar la transmisión de información SSH utiliza diferentes técnicas de manipulación de datos, en los distintos pasos de una transacción. Estas técnicas aplican encriptación simétrica, asimétrica y uso de hash.

Encriptación simétrica

La diferencia entre la encriptación simétrica y la asimétrica está en los componentes que se utilizan para encriptar y desencriptar datos.

La encriptación simétrica es una clase de encriptación donde una clave única puede ser usada para encriptar mensajes a enviar a otra parte, y también para desencriptar los mensajes recibidos de la misma parte. Esto implica que cualquiera que tenga acceso a la clave única podrá encriptar y desencriptar mensajes.

La encriptación simétrica es conocida como “secreto compartido” ó “clave secreta”. En este tipo de encriptación existe una clave única para encriptar y desencriptar, o a lo sumo un par de claves relacionadas de forma sencilla y fácilmente deducible.

SSH usa encriptación simétrica para encriptar toda la conexión. Contrariamente a lo que creen muchos usuarios, el par de claves pública y privada (de encriptación asimétrica) que se generan son usadas solamente para la autenticación, no para la encriptación de la conexión. La encriptación simétrica permite incluso el uso de contraseñas de autenticación contra injerencias no deseadas.

Las partes involucradas en la comunicación a proteger (en nuestro caso siempre cliente y servidor) contribuyen a establecer una clave única de encriptación simétrica, y como resultado ninguna otra parte llega a conocer la misma. La clave única secreta es creada mediante un proceso conocido como “algoritmo de intercambio de claves”. Este intercambio se realiza en el servidor y en cada cliente, y ambas partes logran la misma clave única, independientemente de la información que compartan y la manipulación secreta de la misma. Este proceso se explica con mayor detalle más adelante.

La clave única simétrica, creada mediante un procedimiento con autenticación (el usuario está autenticado en el servidor al realizarlo), es la base de toda la encriptación de los datos que circulan entre ambas partes. Una vez creada la clave única, el resto de los datos deberán ser encriptados con la misma. Este proceso de encriptación se realiza antes de la autenticación de un cliente en el servidor.

SSH puede ser configurado para utilizar una gran variedad de sistemas simétricos de cifrado, como AES, Blowfish, 3DES, CAST128, y Arcfour. Ambas partes (cliente y servidor) pueden definir una lista con sus sistemas de cifrados soportados, ordenándolos por preferencia. La primera opción de la lista de sistemas de cifrados del cliente disponible en el servidor es usado como algoritmo de cifrado en ambas direcciones (cliente-servidor y servidor-cliente).

En Ubuntu 14.04 ambas partes (cliente y servidor) tienen una lista ordenada de cifrados predeterminados como la siguiente: aes128-ctr, aes192-ctr, aes256-ctr, arcfour256, arcfour128, aes128-gcm@openssh.com, aes256-gcm@openssh.com, chacha20-poly1305@openssh.com, aes128-cbc, blowfish-cbc, cast128-cbc, aes192-cbc, aes256-cbc, arcfour.

Esto significa que, si dos equipos con sistema operativo Ubuntu 14.04, se conectan como cliente-servidor entre sí (sin anular los cifrados predeterminados a través de las opciones de configuración), usarán cifrado “aes128-ctr” de encriptación en su conexión.

Encriptación asimétrica

La encriptación asimétrica se diferencia de la simétrica ya que para enviar datos en una sola dirección (ejemplo: cliente-servidor) son necesarias dos claves relacionadas. A una de las claves se la conoce como clave privada, mientras que la otra es llamada clave pública.

La clave pública puede ser compartida con cualquier persona. La misma clave pública está asociada con otra clave (la clave privada), pero lo fundamental es que la clave privada no deriva, ni puede ser relacionada de ninguna manera, con la clave pública. La relación matemática que existe entre un par de claves (una pública y una privada) radica en que la clave pública puede encriptar mensajes que solo pueden ser desencriptados por la clave privada. Esta propiedad es unidireccional, lo que significa que la clave pública no puede desencriptar el mensaje que encripta, ni puede desencriptar ningún otro mensaje que sea encriptado por su clave privada.

La clave privada debe ser mantenida estrictamente en secreto, y no deberá ser compartida con nadie. Este es un requisito fundamental para que el paradigma del cifrado asimétrico funcione. La clave privada es el único componente de todo el sistema capaz de desencriptar mensajes encriptados usando la clave pública relacionada. En virtud de esto, cualquier entidad capaz de desencriptar estos mensajes podrá demostrar así tener el control de la clave privada.

SSH utiliza encriptación asimétrica en solo algunas partes del proceso de conexión. Se usa encriptación asimétrica durante la fase inicial de intercambio de claves, con el fin de configurar la encriptación simétrica (usado para encriptar la sesión en el servidor). En ese momento del proceso, ambas partes (servidor y cliente) generan claves temporales e intercambian la clave pública, con el fin de compartir el secreto que usarán para la encriptación simétrica.

El uso más controvertido de encriptación asimétrica de SSH lo constituye la autenticación con clave. Los pares de claves (pública y privada) pueden ser usados para identificarse en un servidor como cliente. El cliente genera un par de claves (pública y privada) y sube la clave pública en todos aquellos servidores remotos donde pretenda acceder. Esta clave es alojada en un archivo llamado “autorized_keys”, dentro de la carpeta “~/.ssh”, en el directorio raíz que tiene el usuario en el servidor remoto.

Luego de establecida la comunicación segura, encriptada simetricamente entre el servidor y el cliente, el cliente deberá autenticarse para poder acceder al servidor. El servidor puede usar la clave pública almacenada en el mismo para encriptar un mensaje a descifrar por el cliente. Si el cliente prueba que es capaz de desencriptar el mensaje, demuestra que tiene en su poder la clave privada. Solo luego de cumplir con el proceso descripto el servidor prepara el ambiente para el cliente.

Hashing

SSH aprovecha la criptografía hashing como otra forma de manipulación de datos. Las funciones del hash criptográfico están compuestas por métodos de creación de pequeñas “firmas” o resúmenes de partes de información. Los principales atributos distintivos de la criptografía hashing hacen que los mismos no puedan ser descifrados o deducidos, con el fin de descubrir el texto original que les dió origen, y son prácticamente únicos.

Usando la misma función hashing y el mismo mensaje se genera siempre el mismo hash; modificando cualquier parte del mensaje se genera un hash totalmente diferente. Un usuario no puede decifrar el mensaje original utilizando un hash, pero sí puede establecer si un mensaje recibido genera el hash que lo acompaña.

Gracias a las propiedades comentadas, los hash se utilizan principalmente en resguardo de la integridad de datos y también para verificar la autenticidad de las comunicaciones. El principal uso en SSH es con HMAC, ó por sus siglas en castellano CAMH, Código de Autenticación de Mensajes en Base Hash. Estos códigos son usados para asegurar que el texto del mensaje recibido está intacto y no fue modificado.

Como parte de la negociación encriptada simétricamente, detallada anteriormente, se selecciona un Código de Autenticación de Mensajes (ó por su sigla en castellano “CAM”, y en inglés MAC). El algoritmo es seleccionado de la lista de preferencias del cliente. Como explicamos antes, se utilizará el primer algoritmo de la lista del cliente que el servidor soporte.

Cada mensaje que es enviado deberá contener un código de autenticación (CAM), que deberá ser verificado por la otra parte para confirmar la integridad del mensaje. El código de autenticación del mensaje se genera con la clave simétrica compartida (entre el cliente y el servidor), el número de secuencia y el texto del mensaje.

El código de encriptación se envía separado de la información encriptada, en el final del paquete. Este método de encriptar primero el mensaje y luego calcular el código de autenticación es el recomendado por entendidos.

Cómo funciona SSH Probablemente ya tengas una idea del funcionamiento básico de SSH. El mismo utiliza el modelo cliente servidor para identificar a las dos partes y encriptar la información que las mismas comparten.

El servidor espera la conexión en un determinado puerto. El mismo servidor, si puede comprobar las credenciales, es el responsable de establecer una conexión segura, de identificar a la parte que intenta conectarse y de generar el acceso al ambiente correspondiente.

Por el otro lado, el cliente es el responsable de iniciar el proceso de comunicación con el servidor (del tipo TCP), negociando una conexión segura, verificando estár anotado en el servidor y proveyendo las credenciales necesarias para la autenticación.

Una conexión de SSH se realiza en dos etapas separadas y bien diferenciadas. La primer etapa implica acordar y establecer la encriptación para proteger futuras comunicaciones. La segunda etapa implica identificar al usuario (cliente) y definir el tipo de acceso que debe ser brindado.

Negociación de la encriptación para la sesión.

Cuando la conexión del cliente con el servidor (del tipo TCP) se logra, este último presenta al cliente la lista de protocolos que soporta. Si el cliente puede combinar un protocolo de la lista del servidor con uno propio la conexión continúa. Entonces, el servidor expone al cliente su clave pública, con la cual el cliente podrá confirmar si se trata del servidor al que intenta conectarse.

En esta parte del proceso, cliente y servidor negocian una clave de sesión, usando una versión del algoritmo conocido como “Diffie-Hellman”. Este algoritmo (y sus distintas variantes) hace posible que cada parte combine su información privada con la información pública de la otra parte para lograr una clave de sesión secreta idéntica.

La clave de sesión será utilizada para encriptar toda la sesión. Los pares de claves (públicas y privadas) usadas en esta parte del proceso son completamente distintas de las que SSH utiliza para autenticar al cliente en el servidor.

La base del funcionamiento del proceso “Diffie-Hellman” es:

Cliente y servidor acuerdan un numero primo grande, que servirá como valor primario (también llamado “semilla” en términos de agricultura);

Las mismas partes acuerdan también un método de encriptación (generalmente AES), que servirá para tratar los valores como método predefinido;

Independientemente, cada parte genera otro número primo que se mantiene reservado, y no se comparte con la otra parte. Este segundo número primo secreto es usado como clave privada en este proceso (esta clave privada es una diferente de la clave privada usada por SSH para la autenticación);

Utilizando la clave privada generada, el método de encriptación elegido y el primer número primo compartido se genera una clave pública, derivada de la clave privada que puede ser compartida con la otra parte;

Luego, cliente y servidor intercambian las claves públicas generadas;

Cada parte utiliza su clave privada, la clave pública de la otra parte y el primer número primo compartido para generar una clave secreta compartida. Más allá de que cada parte genera su propia clave secreta compartida en procesos de generación independientes, y gracias al método, ambas claves secretas compartidas resultan idénticas.

En consecuencia, la clave secreta compartida es usada para encriptar toda la comunicación que se genere a continuación. Esta clave se utiliza en todo el resto de la comunicación y es conocida como protocolo empaquetado binario. El proceso descripto anteriormente permite a cada parte participar equitativamente en la generación de la clave secreta compartida (ó protocolo empaquetado binario), lo que impide que solo una parte controle el proceso. Esto también permite cumplir con el objetivo de generar una clave secreta compartida idéntica sin enviar información por canales inseguros.

La clave secreta compartida es una clave simétrica, lo que significa que la misma clave usada para encriptar un mensaje puede ser usada también para desencriptarlo del otro lado. El propósito de todo esto es el de empaquetar toda la comunicación para ser enviada por un conducto encriptado, imposible de desencriptar por terceros ajenos a las partes.

Luego de establecer la sesión encriptada, comienza el proceso de autenticación.

Autenticando el acceso del Usuario al Servidor

El próximo paso del proceso esta relacionado con la autenticación del Usuario y la decisión de ingreso al servidor. Existen pocos métodos que pueden ser usados para la autenticación, en base a los que el servidor acepta.

El más simple de todos es probablemente la autenticación por contraseña, en el cual el servidor simplemente solicita la contraseña de la cuenta donde se intenta ingresar. La contraseña es enviada a través de una encriptación negociada, la cual es segura respecto de terceros extraños a ambas partes.

Más allá de que la contraseña puede ser encriptada, este método generalmente no es recomendado debido a las limitaciones en la complejidad de la contraseña. Utilizando scripts automatizados se pueden romper fácilmente contraseñas de complejidad media, comparado con otros métodos de autenticación.

La alternativa más recomendada y popular es el uso del par de claves SSH. El par de claves SSH son claves asimétricas, lo que significa que las dos claves asociadas cumplen diferentes funciones (encriptación y desencriptación respectivamente).

La clave pública es usada para encriptar datos que sólamente pueden ser desencriptados con la clave privada asociada. La clave pública puede ser compartida, porque, no obstante poder encriptar, no existe la posibilidad de descifrar la clave privada desde la pública.

La autenticación usando pares de claves SSH se inicia después de establecida la encriptación simétrica, como describimos en la sección previa. El proceso de autenticación puede ser explicado del siguiente modo:

El cliente inicia el proceso enviando un identificador (para formar el par de claves) hacia el servidor donde pretende identificarse;

El servidor chequea el identificador recibido con el contenido del archivo “authorized_keys”, de la cuenta del cliente que esta intentando acceder;

Si el identificador recibido coincide con la clave pública del archivo, el servidor genera un numero al azar y usa la clave pública para encriptar el mismo;

El servidor envía al cliente el número encriptado como mensaje;

Si el cliente está en poder de la clave privada correspondiente, podrá desencriptar el mensaje usando el número desencriptado como clave;

El cliente combinará la clave desencriptada con la clave de sesión utilizada para encriptar la comunicación ya establecida, y calculará con el algoritmo MD5 el hash de ese valor;

El cliente luego enviará el hash al servidor como respuesta al mensaje recibido;

El servidor utilizará la misma clave de sesión y el número original para calcular también con MD5 el valor por su cuenta. Luego el servidor comparará su propio resultado con el recibido del cliente. Si los dos valores coinciden (has recibido enviado por el cliente y hash calculado por el servidor) ello es prueba suficiente de que el cliente está en posesión de la clave privada correspondiente y el cliente es identificado;

Como se puede apreciar, la asimetría de las claves permiten al servidor encriptar mensajes para enviar al cliente usando la clave pública. El cliente puede probar que está en posesión de la clave privada al desencriptar el mensaje correctamente. Las dos formas de encriptación que fueron usadas (encriptación simétrica como secreto compartido, y encriptación asimétrica como para de claves pública y privada) son capaces de elevar la fortaleza de en este modelo.

Conclusiones: Estudiar las fases de la negociación en las conexiones y cómo funcionan las capas de encriptación en SSH te ayudará a comprender mejor qué sucede en una conexión a un servidor remoto. Esto te ayudará a tener una mejor idea de la relación exitente entre varios componentes y algoritmos, y comprender como encajan todos ellos en conjunto.