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.
Téléportation de primitives cryptographiques par défautInitialisation 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ésRé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 HDè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 ECDHNouvelles 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éatoireL'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 FConclusion
À 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.