Poignée de main SSH en termes simples.

Secure Shell (SSH) est un protocole de couche de transport largement utilisé pour sécuriser les connexions entre les clients et les serveurs. Il s'agit du protocole de base de notre programme Teleport pour un accès sécurisé à l'infrastructure. Vous trouverez ci-dessous une description relativement brève de la prise de contact qui se produit avant d'établir un canal sécurisé entre le client et le serveur et avant de commencer le chiffrement complet du trafic.

Partage de version


La prise de contact commence par le fait que les deux parties s'envoient une chaîne avec le numéro de version. Rien d'extrêmement excitant ne se produit dans cette partie de la prise de contact, mais il convient de noter que la plupart des clients et serveurs relativement modernes ne prennent en charge que SSH 2.0 en raison de défauts de conception dans la version 1.0.

Échange de clés


Dans un processus d'échange de clés (parfois appelé KEX), les parties échangent des informations accessibles au public et obtiennent un secret partagé par le client et le serveur. Ce secret ne peut être découvert ou obtenu à partir d'informations accessibles au public.

Initialisation de l'échange de clés


L'échange de clés commence par le fait que les deux parties s'envoient un message SSH_MSG_KEX_INIT avec une liste des primitives cryptographiques prises en charge et leur ordre préféré.

Les primitives cryptographiques doivent établir les blocs de construction qui seront utilisés pour l'échange de clés, puis le chiffrement complet des données. Le tableau ci-dessous répertorie les primitives cryptographiques prises en charge par Teleport.

Échange de clés (KEX)Chiffrement symétriqueCode d'authentification de message (MAC)Algorithme de clé d'hôte de serveur
curve25519-sha256@libssh.orgchacha20-poly1305@openssh.comhmac-sha2-256-etm@openssh.comssh-rsa-cert-v01@openssh.com
ecdh-sha2-nistp256aes128-gcm@openssh.comhmac-sha2-256ssh-rsa
ecdh-sha2-nistp384aes256-ctr
ecdh-sha2-nistp521aes192-ctr
aes128-ctr
Téléportation de primitives cryptographiques par défaut

Initialisation du protocole Diffie-Hellman sur les courbes elliptiques


Étant donné que les deux parties utilisent le même algorithme pour sélectionner les primitives cryptographiques dans la liste des primitives prises en charge, après l'initialisation, vous pouvez immédiatement commencer à échanger des clés. La téléportation ne prend en charge que le protocole ECDH (Elliptic Curve Diffie-Hellman), de sorte que l'échange de clés commence lorsque le client génère une paire de clés éphémères (clé privée et clé publique associée) et envoie au serveur sa clé publique dans le message. SSH_MSG_KEX_ECDH_INIT .

Il convient de souligner que cette paire de clés est éphémère: elle n'est utilisée que pour l'échange de clés, puis elle sera supprimée. Il est donc extrêmement difficile de mener une classe d'attaques où un attaquant enregistre passivement le trafic crypté dans l'espoir de voler la clé privée dans le futur (comme le prévoit la loi de Yarovaya - environ Trans.). Il est très difficile de voler quelque chose qui n'existe plus. Cette propriété est appelée secret avancé.

Fig. 1. Génération d'un message d'initialisation d'échange de clés

RĂ©ponse de Diffie-Hellman sur les courbes elliptiques


Le serveur attend le message SSH_MSG_KEX_ECDH_INIT et, à réception, il génère sa propre paire de clés éphémères. En utilisant la clé publique du client et sa propre paire de clés, le serveur peut générer un secret partagé K.

Ensuite, le serveur génère quelque chose appelé le hachage d'échange H et le signe, générant un hachage HS signé (plus sur la figure 3). Le hachage d'échange et sa signature ont plusieurs objectifs:

  • Étant donnĂ© que le hachage d'Ă©change comprend un secret partagĂ©, cela prouve que l'autre partie a pu crĂ©er un secret partagĂ©.
  • Le cycle de hachage / vĂ©rification du hachage et de la signature d'Ă©change permet au client de vĂ©rifier que le serveur possède la clĂ© privĂ©e de l'hĂ´te, et donc le client est connectĂ© au bon serveur (si le client peut faire confiance Ă  la clĂ© publique correspondante, plus Ă  ce sujet plus tard).
  • En signant le hachage au lieu de signer les donnĂ©es d'entrĂ©e, la taille des donnĂ©es en cours de signature est considĂ©rablement rĂ©duite et conduit Ă  une prise de contact plus rapide.

Le hachage d'échange est généré en prenant le hachage (SHA256, SHA384 ou SHA512, selon l'algorithme d'échange de clés) des champs suivants:

  • Magic M Version client, version serveur, message client SSH_MSG_KEXINIT , message serveur SSH_MSG_KEXINIT .
  • ClĂ© publique (ou certificat) de l' HPub serveur HPub . Cette valeur (et sa clĂ© privĂ©e HPriv correspondante) est gĂ©nĂ©ralement gĂ©nĂ©rĂ©e lors de l'initialisation du processus, et non pour chaque prise de contact.
  • ClĂ© publique client
  • ClĂ© publique du serveur B
  • Secret partagĂ© K

Avec ces informations, le serveur peut construire le message SSH_MSG_KEX_ECDH_REPLY utilisant la clé publique éphémère du serveur B , la clé publique de l' HPub serveur HPub et la signature sur le hachage d'échange HS . Voir fig. 4 pour plus de détails.


Fig. 2. Génération du hachage d'échange H

Dès que le client a reçu SSH_MSG_KEX_ECDH_REPLY du serveur, il a tout le nécessaire pour calculer le secret K et le hachage d'échange H

Dans la dernière partie de l'échange de clés, le client récupère la clé publique hôte (ou le certificat) de SSH_MSG_KEX_ECDH_REPLY et vérifie la signature du hachage d'échange HS confirmant la propriété de la clé privée de l'hôte. Pour empêcher les attaques de type «homme au milieu» (MitM), après vérification de la signature, la clé publique (ou le certificat) de l'hôte est vérifiée par rapport à la base de données locale des hôtes connus; si cette clé (ou certificat) n'est pas approuvée, la connexion est déconnectée.

  L'authenticité de l'hôte 10.10.10.10 (10.10.10.10) 'ne peut pas être établie.
 L'empreinte digitale de la clé ECDSA est SHA256: pnPn3SxExHtVGNdzbV0cRzUrtNhqZv + Pwdq / qGQPZO3.
 Voulez-vous vraiment continuer Ă  vous connecter (oui / non)? 
Le client SSH propose d'ajouter la clé d'hôte à la base de données locale des hôtes connus. Pour OpenSSH, il s'agit généralement de ~/.ssh/known_hosts

Un tel message signifie que la clé présentée ne se trouve pas dans votre base de données locale d'hôtes connus. Un bon moyen d'éviter de tels messages consiste à utiliser des certificats SSH (ce que Teleport fait par défaut) au lieu de clés, ce qui vous permet de simplement stocker le certificat de l'autorité de certification dans une base de données locale d'hôtes connus, puis de vérifier tous les hôtes signés par cette autorité de certification.


Fig. 3. Génération d'une réponse d'échange de clés ECDH

Nouvelles clés


Avant de commencer le chiffrement de masse des données, la dernière mise en garde est restée. Les deux parties doivent créer six clés: deux pour le chiffrement, deux vecteurs d'initialisation (IV) et deux pour l'intégrité. Vous vous demandez peut-être pourquoi il y a tant de clés supplémentaires? K n'est-il pas assez secret? Non, pas assez.

Tout d'abord, pourquoi avons-nous besoin de clés distinctes pour le chiffrement, l'intégrité et IV. L'une des raisons est liée au développement historique de protocoles tels que TLS et SSH, à savoir la négociation de primitives cryptographiques. Dans certaines primitives cryptographiques sélectionnées, la réutilisation des clés n'est pas un problème. Mais, comme Henryk Hellstrom l'explique correctement, si les primitives sont incorrectement sélectionnées (par exemple, AES-256-CBC pour le chiffrement et AES-256-CBC-MAC pour l'authentification), les conséquences peuvent être désastreuses. Il convient de noter que les développeurs de protocoles abandonnent progressivement cette flexibilité pour rendre les protocoles plus simples et plus sûrs.

Ensuite, pourquoi les clés de chaque type sont-elles utilisées?

Les clés de chiffrement garantissent la confidentialité des données et sont utilisées avec un chiffrement symétrique pour chiffrer et déchiffrer un message.

Les clés d'intégrité sont couramment utilisées avec le code d'authentification de message (MAC) pour garantir l'authenticité du texte chiffré. En l'absence de contrôles d'intégrité, un attaquant peut modifier le texte chiffré transmis sur des canaux ouverts et vous déchiffrerez un faux message. Ce schéma est généralement appelé Encrypt-then-MAC .

Il convient de noter que les chiffrements AEAD modernes ( chiffrement authentifié avec des données jointes, lorsqu'une partie du message est chiffré, une partie reste ouverte et le message entier est complètement authentifié) comme aes128-gcm@openssh.com et chacha20-poly1305@openssh.com n'utilisent pas réellement la clé dérivée l'intégrité pour le MAC, et effectuer l'authentification au sein de leur structure.

Les vecteurs d'initialisation (IV) sont généralement des nombres aléatoires utilisés comme entrée pour un chiffrement symétrique. Leur objectif est de s'assurer qu'un même message, chiffré deux fois, ne mène pas au même texte chiffré. La nécessité d'une telle procédure est parfaitement démontrée par la célèbre image du pingouin Tux, cryptée en mode livre de codes électronique (ECB).


De gauche à droite. (1) Effacer le texte sous forme d'image. (2) Un cryptogramme obtenu par cryptage en mode ECB. (3) Un cryptogramme obtenu par cryptage dans un mode autre que la BCE. L'image est une séquence de pixels pseudo-aléatoire

L'utilisation (et le piratage) de vecteurs IV est un sujet intéressant en soi, sur lequel Filippo Walsord a écrit .

Enfin, pourquoi les clés viennent-elles par paires? Comme l'a noté Thomas Pornin , si une seule clé d'intégrité est utilisée, un attaquant peut reproduire le dossier qui lui est envoyé au client, et il le considérera comme valide. Avec des clés d'intégrité appariées (sur le serveur et le client), le client vérifiera l'intégrité du texte chiffré et cette astuce ne fonctionnera pas.

Maintenant, en comprenant pourquoi ces clés sont nécessaires, voyons comment elles sont générées selon le RFC :

  • DĂ©marrage du vecteur IV du client au serveur: HASH(K || H || «A» || session_id)
  • DĂ©marrage du vecteur IV du serveur au client: HASH(K || H || «B» || session_id)
  • ClĂ© de chiffrement du client au serveur: HASH(K || H || «C» || session_id)
  • ClĂ© de chiffrement du serveur au client: HASH(K || H || «D» || session_id)
  • ClĂ© de contrĂ´le d'intĂ©gritĂ© du client au serveur: HASH(K || H || «E» || session_id)
  • ClĂ© de contrĂ´le d'intĂ©gritĂ© du serveur au client: HASH(K || H || «F» || session_id)

Ici, l'algorithme de hachage SHA est utilisé {256, 384 ou 512} selon l'algorithme d'échange de clés et le symbole || implique la concaténation, c'est-à-dire la traction.

Dès que ces valeurs sont calculées, les deux parties envoient SSH_MSG_NEWKEYS pour informer l'autre côté que l'échange de clés est terminé et que toutes les communications futures doivent avoir lieu en utilisant les nouvelles clés créées ci-dessus.


Fig. 4:. Génération initiale de vecteurs IV. La génération pour d'autres clés se produit selon le même schéma, si nous remplaçons respectivement A et B par C, D, E et F

Conclusion


À ce stade, les deux parties se sont mises d'accord sur les primitives cryptographiques, ont échangé des secrets et généré des éléments clés pour les primitives sélectionnées. Désormais, un canal sécurisé peut être établi entre le client et le serveur, ce qui garantira la confidentialité et l'intégrité.

C'est ainsi que les négociations SSH établissent une connexion sécurisée entre les clients et les serveurs.

Source: https://habr.com/ru/post/fr474654/


All Articles