---
title: "Sécurité des réseaux : les utilisateurs"
date: 2022-10-25
tags: ["authetification", "SSO", "kerberos"]
categories: ["Sécurité des réseaux", "Cours"]
matjax: true
---

Il est question ici de savoir comment authentifier les utilisateurs de manière
la plus sécurisée possible. On verra donc le *Single Sign On*, que se soit sur
un réseau local avec *Kerberos* ou sur le web. On parlera aussi de délégation
d'autorisation et d'authentification firte (2FA, FIDO).

## SSO

Pour faire une analogie, prenons l'exemple d'une zone protégée: notre identité
est vérifiée à l'entrée, un badge nous est fourni avec un acces à certaines
zones.

Le but est d'entrée **le moins possible les informations d'indentification**

## Kerberos

Kerberos est un protocole d'authentification qui repose sur des clé secrète et
l'utilisation de tickets. Kerberos se base sur les exigence suivante:

 * **sûr**: une attaque du type MitM ne doit pas permettre à l'attaquant
  d'obtenir des informations pour usurper l'identité de sa victime.
 * **fiable**: doit pouvoir s'appuyer sur une architecture redondante et
  résiliente.
 * **transparent**: l'utilisateur ne doit pas être conscente du processus
  d'authentification.
 * **évolutif**: le système doit pouvoir passer à l'échelle.

### Protocole de Needham Schroeder

C'est une protocole d'authentification conçu pour l'utilisation dans un réseau
informatique non sûr.

Soit \\(A\\) et \\(B\\) deux systèmes communiquant sur un réseau:

 * \\(S\\) et le serveur de confiance pour les deux protagonistes
 * \\(K_{AS}\\) est la clé symétrique connue de \\(A\\) et \\(S\\)
 * \\(K_{BS}\\) est la clé symétrique connue de \\(B\\) et \\(S\\)
 * \\(N_{A}\\) et \\(N_{B}\\) des nonces pour \\(A\\) et \\(B\\)

Voici le protocole:

 1. \\( A \to S : A, B, N_{A} \\)
 2. \\( S \to A : \\{ N_{A}, K_{AB}, B, \\{ K_{AB},A\\}K_{BS}\\}K_{AS} \\)
 3. \\( A \to B : \\{K_{AB}, A\\}K_{BS}\\)
 4. \\( B \to A : \\{N_{B}\\}K_{AB}\\)
 5. \\( A \to B : \\{N_{B} - 1\\}K_{AB}\\)

Ce protocole est **sensible au attaques par rejeu**. Cependant, dans son
implémentation au sein de *Kerberos*, un *timestamp* est ajouté.

\\(\\{K_{AB}, A\\}K_{BS}\\) représente le **ticket Kerberos**.

### Le protocole Kerberos

Kerberos utilise un *Serveur d'authentification* noté *SA* qui connait **tous**
les mots de passe. Il partage une clé secrète *unique* lorsqu'un utilisateur
demande un service à un serveur:

 1. Le module client du poste de travail envoi l'identifiant, le mot de passe 
  l'identité de A et de B au *SA* :  
  \\( A \to SA : ID_{A}, User_{A}, Pass_{A}, ID_{B} \\)
 2. Le *SA* authentifie l'utilisateur
 3. Le *SA* créé un ticket contenant l'identité de A et de B, le tout chiffré
  avec le secret partagé entre A et B:  
  \\( \\{ID_{A},ID_{B} \\}K_{SA,B} \\)
 4. le *SA* envoi le ticket au poste client.

Le ticket contient :
 
 * l'identifiant du serveur afin qu'il vérifie qu'il a correctement déchiffré le 
  message
 * l'identifiant du poste client afin de connaitre l'origine de la demande (
  poste client de l'utilisateur)
 * l'adresse du poste client ou son nom DNS afin d'éviter l'usurpation
   d'identité.

Le but est bien de **réduire** le nombre de fois ou l'utilisateur saisit son mot
de passe. Mais problème: **il est  passé en clair!**

### Le serveur de ticket

Solution: déporter l'octroi de ticket sur un serveur dédié : le *TGS*' *Ticket
Granting Service*.

 1. Le client demande un ticket d'octroi de ticket de la part de l'utilisateur
    au SA:    
  \\( A \to SA : User, TGS, ID_{A} \\)
 2. Le SA répond par un ticket chiffré avec une clé dérivée du mot de passe de
    l'utilisateur. Lorsque la réponse arrive, le client demande le mot de passe à
    l'utilisateur, génère la clé et déchiffre le message: 
  \\( SA \to A : \\{ Ticket_{TGS}\\}_{mdp} \\)
 3. le client demande un ticket d'octroi au service de la part de l'utilisateur
    :  
  \\( A \to TGS : ID_{A}, User, ID_{B}, Ticket_{TGS} \\)
 4. le TGS déchiffre le ticket et vérifie la validité du déchiffrement par la
    présence de son ID, si tout se passe bien il génère un ticket pour accorder
    l'accès au service :  
  \\( TGS \to A : Ticket_S \\)
 5. Le client demande l'accès au service de la part de l'utilisateur 
  \\( A \to S : A, Ticket_S \\)

Où:

 * \\( Ticket_{TGS} = \\{ A, addr_A, TGS, timestamp \\}K_{SA,TGS}\\)
 * \\( Ticket_S = \\{A, S, addr_C, timestamp\\}K_{TGS,S}\\)

Le but est de détenir un ticket qui prouve mon authentification. Le but est
que les éléments puissent prouver leurs identités les un les autres.

En pratique le protocole est plus compliqué, une clé est ajoutée dans le ticket
du TGS. Cette clé est utilisée régulièrement afin de résoudre un challenge. Elle 
et connue que su TGS et du client. La même technique est utilisée entre le
serveur le le client.

## WebSSO

WebSSO est un protocole de *Single Sing-On* appliqué au web. On dénombre deux
protocoles principaux: *CAS* et *OpenID*.

WebSSO se base sur les cercle de confiance, les fournisseurs d'identités (IDP)
et les fournisseurs de services (SP)

### CAS - Central Authentication Service

C'est un protocole utilisé pour les réseaux d'entreprise. Ici le serveur n'a pas
à connaitre les client, la confiance se fait par les certificats serveurs,

Il est, comme Kerberos, basé sur des notions d'échange de tickets.

Il est pertinent dans un réseau fermé et un environnement maitrisé.

### OpenID

Ce protocole est  utilisé par les sites web grand public et les applications
mobiles, il est basé sur [Oauth2](https://fr.wikipedia.org/wiki/OAuth).

OpenID  permet d'accéder à une ressource sans connaitre son propriétaire ni ses
identifiants. On ne gère pas *d'authentification* mais **l'autorisation**.

4 entités sont utilisées:
 
 * client;
 * propriétaire (humain)
 * le serveur
 * le serveur d'autorisation

## Authentification forte

Il est question ici d'utiliser plus d'un facteur d'authentification :

 * basé sur la connaissance
 * basé sur la propriété
 * basé sur l'inhérence

## FIDO2

Les mots de passe ont toujours posé problèmes : un même mot de passe pour
plusieurs, voire tous les services par exemple. Le protocole *FIDO2* propose un
token d'authentification qui utilise le *challenge-response*.

Le token génère une **paire de clé** (cryptographie asymétrique) **par site**.
La partie publique est envoyée au site.

Ces éléments sont stockée sur une puce sécurisée.

Lors de l'authentification, le serveur envoie un challenge. Celui-ci est
envoyé à la clé. Celle-ci répond avec:

\\( \\{ ID_{client}, ID_{serveur}, Challenge\\}sign_{(priv)}\\)

### Attestation

L'attestation est une signature posée sur la clé publique par un tiers. Le
serveur doit connaitre la clé qui sert à signer.

Il esxiste plusieurs types de clé:

 * Aucune clé;
 * auto-signé;
 * `basic attestation`: la clé privée du constructeur est posée sur le token, en
   cas de compromission d'un token, **ils le sont tous**;
 * `ECDSA`: clé avec une partie forgée, ce fonctionnement est lourd en terme de
   calcul et difficile à implémenter, utilisé pour des éléments critiques;
 
La vérification de l'utilisateur (présence, code PIN) est conseillée mais pas
imposée par la norme.
