Langages de programmations
Chiffrement pour les ressources ne pouvant fournir une connexion sécurisée
Certains des IoT choisis pour ce travail de Bachelor ne sont pas suffisamment puissants pour offrir une communication sécurisée avec le protocole TLS. Afin de pallier à ce problème le serveur d’autorisation doit pouvoir émettre des clés de chiffrement à destination des clients et des ressources. Étant donné que le protocole Oauth2.0 est très fortement dépendant du protocole TLS, les éléments suivants ne font pas partie du standard. En outre, afin de simplifier le développement du serveur d’autorisation prototype, seuls les algorithmes de cryptage symétrique sont supportés. Si la communication entre la ressource protégée et le client ne peut être sécurisée via TLS, le serveur génère une clé de chiffrement symétrique partagée (shared key) qui permettra d’encrypter les messages transitant entre les deux entités. La longueur de la clé dépend du type de cryptage supporté et est déterminé à l’enregistrement de la ressource protégée ciblée.
Dans chacun des quatre processus d’obtention d’autorisation, la clé de chiffrement partagée est retournée par le serveur d’autorisation à la même étape que le jeton d’accès. Le processus qui décrit le transfert de données chiffrées entre le serveur de ressource et le client est l’objet du sous chapitre 4.2.9 « proof of possession ». Contre-indications : Étant donné que le flux « implicit » ne prévoit pas de méthode pour remplacer un JWT échu et que l’absence de TLS entre le client et la ressource contraint à mettre en place des systèmes de sécurité très restrictifs (délais d’expiration très court, nonce, etc…), ce flux est contre indiqué dans cette démarche. De plus, la clé de chiffrement est exposée au « user-agent » de la même manière que le jeton d’accès, ce qui pose des risques de sécurité supplémentaires.
Ressource ne pouvant émettre de requêtes https
Dans le cadre de ce travail de Bachelor, l’Arduino UNO (un des IoT sélectionnés) est incapable de gérer le protocole TLS que ce soit en tant que client ou en tant que serveur. Sans support du https, notre ressource protégée est sensible à l’attaque de type « man-in-the-middle ». Il s’agit d’une attaque couramment utilisée sur des réseaux où les communications ne sont pas cryptées. Elle vise à intercepter les communications entre deux parties. Il est possible de partiellement résoudre ce problème de sécurité en encryptant les données directement au niveau de la couche message. Lorsque le développeur ou tout autre utilisateur final enregistre la ressource protégée au près du serveur d’autorisation, il négocie les modalités de cryptage souhaité. Si le serveur de ressource est enregistré comme ne pouvant contacter le serveur d’autorisation sous TLS, celui-ci utilisera le « resource_secret » généré automatiquement à l’enregistrement pour encrypter les informations de la requête. Le prototype du serveur d’autorisation supporte uniquement l’algorithme de cryptage symétrique AES en mode ECB et CBC.
Il est important de préciser que ce système fonctionne uniquement en partant du principe que la ressource protégée est capable de maintenir la confidentialité de son mot de passe faisant office de clé de cryptage (resource_secret). De ce fait, elle présentera son identifiant unique sans le mot de passe au serveur d’autorisation pour éviter que celui-ci ne puisse être intercepté et que les communications ne soient compromises. En outre, ce dernier point signifie que le serveur d’autorisation ne peut pas authentifier la ressource protégée, ce qui déroge au protocole prévu pour l’introspection de jeton. Dans l’état actuel, le prototype n’implémente pas de méthode supplémentaire permettant de clairement identifier et authentifier un serveur de ressource sans connexion sécurisée. Par conséquent, il est possible d’usurper l’identité d’une ressource et d’introspecter un jeton d’accès sans en avoir l’autorisation. La réponse restera tout de même ininterprétable sans la clé de cryptage. En outre, dans le cadre d’une attaque par le milieu et par rejeu, il est possible pour un attaquant de copier une réponse d’introspection et de se faire passer pour le serveur d’autorisation dans le but de faire croire à une ressource qu’un jeton d’accès est valide. Pour corriger cette vulnérabilité (attaque par le rejeu), la ressource protégée doit pouvoir conserver un identifiant unique (nonce) retourné par le serveur d’autorisation et considérer toute réponse identique comme étant compromise.
Proof of Possession (PoP) La spécification Oauth2.0 sur les « Bearer Token » standardisée par la RFC 6750 défini que tout parti en possession d’un jeton d’accès de ce type à le droit d’accéder à la ressource protégée associée sans démontrer qu’il a le droit de l’utiliser (ou de le posséder) Cela signifie qu’un serveur de ressource n’a pas de garantie qu’un jeton d’accès soumis par un client, ait réellement été émis pour celui-ci. Par analogie, le traditionnel nom d’utilisateur et mot de passe qu’on utilise tous les jours pour s’authentifier pose exactement le même problème. En effet, il y a une différence entre authentifier et identifier. Un mot de passe permet d’authentifier un utilisateur mais pas de l’identifier. Il n’offre pas de garantie que la personne qui l’utilise est bien le propriétaire de la ressource à laquelle il donne accès. Pour réduire ce risque, certains mécanismes peuvent être mis en place comme par exemple le « Two-factor authentication (2FA) ».
Cette méthode permet d’identifier un utilisateur en lui demandant de transmettre en plus de son mot de passe, un code d’authentification qui lui a été préalablement envoyé par sms ou email. Par conséquent, le mot de passe à lui seul, ne permet plus d’accéder à une ressource et c’est exactement l’objectif de la spécification supplémentaire Proof-of-Possession : éviter qu’un jeton d’accès à lui seul ne suffise à accorder l’accès à une ressource protégée. Il existe à ce jour pas de standard décrivant l’architecture du PoP mais l’IETF a publié une version préliminaire sur ce sujet à titre d’information. Le processus qui permet d’obtenir la preuve de la possession diffère sensiblement en fonction du type de clé utilisé (symétrique ou asymétrique). Étant donné que le prototype du serveur d’autorisation ne supporte que les clés symétriques, seul ce flux sera présenté dans le cadre de ce travail de Bachelor.
Interaction entre le serveur de ressource et le client sans TLS
Afin d’utiliser le protocole Oauth2.0 pour sécuriser un réseau d’IoT, il est nécessaire de prendre en compte certains facteurs limitants propre à ce type de ressource et de trouver des solutions. Les principaux facteurs limitants que j’ai rencontrés sont principalement liés au manque de mémoire et de puissance de certains IoT. Quand on travaille avec des JWT et Oauth2.0 en général, il faut s’attendre à devoir gérer des requêtes transportant de longues chaines de caractères et cela peut être problématique sur certains IoT comme l’Arduino UNO. La solution consiste à transporter le strict minimum d’informations requises permettant d’atteindre les objectifs de sécurité fixés. En second lieu, il existe une autre famille de jetons d’accès nommé « CBOR Object Signing and Encryption (COSE) » (RFC 8152) standardisé par le « Concise Binary Object Representation (CBOR) » (RFC 7049) qui offre une structure pour créer des « CBOR Web Token (CWT) ».
L’objectif des CWT est d’offrir le même système de représentation d’une autorisation qu’un JWT mais optimisé pour des appareils ayant des capacités très limitées. Malheureusement, je n’ai trouvé aucune librairie activement maintenue pour ces types de jetons d’accès. En outre, certains IoT ne sont pas assez puissants pour communiquer avec le protocole TLS. Si l’interaction entre le client et la ressource protégée ne peut être cryptée au niveau de la couche réseau (https), le client ne peut pas transmettre la clé symétrique de façon traditionnelle. En effet, l’absence de TLS expose la ressource protégée à une attaque de type « man in the middle ». Jacob Ideskog a proposé une solution basée sur la preuve de la possession lors d’une conférence organisée par Nordic APIS. Comme mentionné dans le chapitre sur les clés de chiffrement partagées, l’idée est que le serveur d’autorisation puisse émettre au même titre que pour le « proof-of-possession » une clé symétrique qui sera partagée entre le client et la ressource cible. Seulement au lieu de comparer les deux clés pour obtenir la preuve que le client est autorisé à utiliser un jeton d’accès, les deux entités utilisent cette clé cryptographique partagée pour directement encrypter les données qu’ils se transmettent.
|
Table des matières
Liste des tableaux
Liste des figures
1. Introduction
1.1 Pourquoi Oauth 2
2. Objet connecté
2.1 L’internet des objets (IoT)
2.2 Étude de faisabilité
2.2.1 Arduino UNO
2.2.1.1 Support TLS :
2.2.1.2 Mode de cryptage AES utilisé
2.2.1.3 Librairie REST
2.2.1.4 Conclusion de l’étude de faisabilité
2.2.2 NodeMCU
2.2.2.1 Support TLS :
2.2.2.2 Mode de cryptage AES utilisé
2.2.2.3 Librairie REST
2.2.2.4 Conclusion de l’étude de faisabilité
2.2.3 Raspberry Pi 3b+
2.2.3.1 Conclusion de l’étude de faisabilité
3. Choix d’implémentation
3.1 Langages de programmations
3.1.1 C/C++
3.1.2 PHP
3.2 Outils
3.2.1 SHELL
3.2.2 Make
3.2.3 Docker
3.2.4 Docker-compose
4. Le protocole Oauth2
4.1 Internet Engineering Task Force (IETF)
4.2 Le framework d’autorisation Oauth2
4.2.1 Les rôles
4.2.2 Le jeton d’accès
4.2.2.1 La famille des JOSE
4.2.2.2 Les JWK
4.2.3 L’enregistrement
4.2.3.1 Le client
4.2.3.2 La ressource
4.2.4 Authentification
4.2.5 Obtention d’un jeton d’accès
4.2.5.1 Client credentials
4.2.5.2 Resource Owner Password Credentials
4.2.5.3 Implicit Grant
4.2.5.4 Authorization Code Grant
4.2.5.5 Remplacer un jeton d’accès
4.2.5.6 Cas défavorables
4.2.6 Chiffrement pour les ressources ne pouvant fournir une connexion sécurisée
4.2.7 Accéder à une ressource
4.2.8 Token Introspection
4.2.8.1 Ressource ne pouvant émettre de requêtes https
4.2.8.2 Risque lié au choix du mode de cryptage
4.2.9 Proof of Possession (PoP)
4.2.9.1 Obtention de la clé symétrique
4.2.9.2 Interaction entre le serveur de ressource et le client avec TLS
4.2.9.3 Interaction entre le serveur de ressource et le client sans TLS
5. Conclusion
6. Glossaire
Bibliographie
Annexe 1 : Liste des dépendances
Annexe 2 : Installation du serveur d’autorisation
Annexe 3 : Installation du Raspberry PI 3b+
Annexe 4 : Installation de l’Arduino IDE
Annexe 5 : Installation de l’Arduino UNO et du NodeMCU
Télécharger le rapport complet