web-dev-qa-db-fra.com

Comment fonctionne l'authentification par clé publique ssh?

Ma compréhension de base est la suivante:

  • Le serveur [connecté à] sshd utilise la clé publique pour crypter certains messages
  • Le ssh ou ssh-agent Du client le déchiffre et renvoie quelque chose (la somme de contrôle du message? Sa signature?)
  • sshd du serveur vérifie que cela est cohérent avec le message d'authentification de l'utilisateur

Mais quels sont les détails? Qu'est-ce qu'un "message", qu'est-ce que ssh(-agent) renvoie? Est-ce que faire cela avec le même message original encore et encore donnerait toujours la même communication?

Ce processus d'authentification peut-il être rejoué via les outils bash si ssh-agent Est utilisé? Par exemple. les clés publiques fournies par ssh-agent peuvent être obtenues via ssh-add -L, qu'en est-il du reste du processus? Ou cela nécessiterait-il une connexion manuelle à la prise $SSH_AUTH_SOCK Unix et une communication de bas niveau?


En relation: le dialogue Server-Bob de Thomas ici , bien que cela suggère que le client signe simplement des données aléatoires qui seront ensuite vérifiées par rapport à toutes les clés publiques de l'utilisateur du serveur authenticated_keys. Cette illustration , d'autre part, prétend que le message est crypté avec la clé publique de l'utilisateur précédemment déterminé (pas celle du cryptage ssh) et le client génère la somme de contrôle qui dépend également d'un ID de session aléatoire. Laquelle est correcte? Ou les deux ne racontent-ils qu'une partie de l'histoire réellement plus complexe?

46
Tobias Kienzler

Les détails de l'authentification dépendent de la version du protocole et du type de clé. Dans tous les cas, il y a toujours un défi, avec un certain hasard pour éviter les attaques de rejeu. Lorsque la clé utilisateur est de type DSA, une véritable signature numérique est nécessairement impliquée, car DSA est un algorithme de signature uniquement. L'article auquel vous liez montre quelque chose qui suppose que la clé utilisateur peut effectuer un chiffrement asymétrique; Je suppose que c'est quelque chose que SSHv1 a fait (dans SSHv1, toutes les clés étaient RSA, et RSA peut faire un cryptage asymétrique). Pour le protocole actuel (SSHv2), l'authentification du client basée sur une clé publique est spécifiée dans RFC 4252 , section 7.

Le concept de base reste le même: le client prouve son contrôle de la clé privée en effectuant une opération qui nécessite la connaissance de cette clé, mais telle que l'opération "inverse" puisse se faire avec la clé publique qui se trouve dans le .ssh/authorized_keys sur le serveur.

15
Thomas Pornin

En bref:

  • SSHv1: le serveur crypte un message sur une clé publique stockée dans authorized_keys, le client doit le déchiffrer et renvoyer sa somme de contrôle (modifiée par un ID de session)
  • SSHv2: Le client signe un message (selon l'ID de session) et transmet la signature sans le message mais avec la clé publique utilisée. Le serveur recrée ensuite le message et vérifie la signature (à condition que la clé publique se trouve réellement dans authorized_keys)

Le document PROTOCOL.agent résume ceci:

Les clés de protocole 1 et de protocole 2 sont séparées en raison de l'utilisation cryptographique différente: les clés RSA privées du protocole 1 sont utilisées pour déchiffrer les défis qui ont été chiffrés avec la clé publique correspondante, tandis que les clés privées du protocole 2 RSA sont utilisées pour signer les défis avec une clé privée pour vérification avec la clé publique correspondante. Il est considéré comme une pratique peu judicieuse d'utiliser la même clé pour la signature et le chiffrement.

Voici la section pertinente SSHv2 de RFC 4252 :

Pour effectuer une authentification réelle, le client PEUT alors envoyer un
signature générée à l'aide de la clé privée. Le client PEUT envoyer le
signature directement sans d'abord vérifier si la clé est
acceptable. La signature est envoyée à l'aide du paquet suivant:

  byte      SSH_MSG_USERAUTH_REQUEST
  string    user name
  string    service name
  string    "publickey"
  boolean   TRUE
  string    public key algorithm name
  string    public key to be used for authentication
  string    signature

La valeur de "signature" est une signature par la clé privée correspondante sur les données suivantes, dans l'ordre suivant:

  string    session identifier
  byte      SSH_MSG_USERAUTH_REQUEST
  string    user name
  string    service name
  string    "publickey"
  boolean   TRUE
  string    public key algorithm name
  string    public key to be used for authentication

Lorsque le serveur reçoit ce message, il DOIT vérifier si le
La clé fournie est acceptable pour l'authentification, et si c'est le cas, elle DOIT
vérifiez si la signature est correcte.

29
Tobias Kienzler