sdk_common/doc/Auth-Specs.md
2024-02-19 10:51:16 +01:00

20 KiB

# Auth - Specs

1. Objectif

Développer un système de login sécurisé utilisant les clés cryptographiques de Bitcoin et sa timechain (via un réseau Signet personnalisé, appelé "side chain") ainsi qu'un système de relais de messages entre parties prenantes. Le concept de Silent Payment est employé pour authentifier les utilisateurs sans réutilisation d'adresses, tout en utilisant une approche de calcul multipartite (MPC) pour une gestion sécurisée et distribuée des clés. Déployer une interface de login conforme aux wireframes.

2. Portée

Ce système couvrira la conception et le développement de l'architecture d'authentification, incluant la génération, la gestion, et la validation des identités numériques à travers des formats de conformité spécifiques (Portable Contract Document et Portable Request Document). Il intégrera également l'authentification des utilisateurs, la connexion via des tiers, la récupération d'identités, et une gestion de session basée sur un cache avec des contraintes de sécurité renforcées. La solution sera conçue pour des environnements hautement sécurisés, nécessitant une haute disponibilité, performance, et évolutivité.

3. Documents de référence

Voir _Doc_references.md.

4. Authentification des utilisateurs

Les utilisateurs doivent pouvoir s'authentifier en utilisant un mot de passe et les données exif d'une image dite de login mise en cache dans IndexedDB pour les navigateurs et les applications mobiles, sinon en mémoire pour tous autres dispositifs dont l'IoT et une partie venant de membres choisi par les gestionnaires des membres des ItemProcess .

Le système utilisera les clés cryptographiques de Bitcoin pour une authentification sécurisée via un HD Wallet transparent, intégrant le concept de Silent Payment pour éviter la réutilisation d'adresses. Les annuaires présents par rôles dans les contrats sont des listes d'adresses Silent Payments avec leurs third parties.

Les utilisateurs sont reconnus par uneadresse SP dans un ou plusieurs rôles dans un ItemProcess. Ces ItemProcess préalablement publiés et relayés par les relais décrivent les conditions de validation des identités. Par process, les identités appelées techniquement member.

Chaque relais permet d'accéder à la liste des process, de créer, recomposer (recover) et révoquer (revoke) une identité, et de la compléter par ItemProcess dans lequel l'utilisateur a un rôle (onboarding).

5. Connexion via des tiers

Le système offrira la possibilité de se connecter via des services tiers (tels que OAuth2, avec Google, GitHub, etc.), permettant une intégration fluide avec les écosystèmes existants sans dégrader l'expérience utilisateur.

Pour cela, les flux de 4NK agissent en "proxy" transparent devant les flux API des services concernés, et les tokens d'accès sont ajoutés aux données de member. En parrallèle des flux existant, les hash des requêtes API et de leurs réponses sont signés des clés des parties prenantes pour une vérification de la conformité des données par rapport aux ItemProcess 4NK.

6. Fonctionnalité de récupération de mot de passe

En cas d'oubli de mot de passe, les utilisateurs pourront récupérer leur accès depuis une nouvelle identité (recover) après avoir révoqué l'ancienne identité, via un processus sécurisé, impliquant une vérification d'identité et l'échange de secrets chiffrés conformément aux protocoles établis.

Une image de révocation est générée à la création d'une identité pour pouvoir dépenser un UTXO dit alors de révocation, avec les flux RequestPcd et RequestPrd correspondants.

7. Gestion de session basée sur un cache

Le système ne maintiendra pas de session traditionnelle sur le serveur. La navigation de l'utilisateur persiste grâce à un cache local dans IndexedDB ou en mémoire, avec une politique de sécurité stricte forçant la resaisie du mot de passe après un rafraîchissement de la page ou une inactivité prolongée, déterminée par une durée maximale sans login.

8. Wallet

Les transactions SP ont besoin de 2 clés privées Bitcoin, l'une critique sur la dépense des jetons, l'autre qui lève la confidentialité (partageable dans certains cas) :

  • Clé de dépense : la clé qui prouve sa détention par la capacité de dépenser un UTXO d'une transaction SP.
  • Clé de scan : la clé qui permet de détecter qu'une transaction SP nous est destinée.

Il y a 3 paires de ces clés privées :

  • 2 paires pour les données exif de l'image de login : l'une pour les transactions sur le signet, l'autre pour le mainnet.
  • 1 paire pour les données exif de l'image de révocation : pour les transactions de révocation sur le signet.

Techniquement ces clés sont identiques et générées de la même manière.

Chaque clé possède un chemin de dérivation spécifique et propre à son réseau (/0 pour le mainnet, /44 pour le signet).

Afin de constituer un portefeuille unique de clés du signet et du mainnet on génère un HD Wallet.

L'aléatoire pour la génération des clés est critique, et il convient de choisir un aléatoire fourni par une librairie de référence (rand pour le Rust).

Dans l'ordre on génère donc :

  1. Clé privée de dépense du login du signet spend_recover.
  2. Clé privée de scan du login du signet scan_recover.
  3. Clé privée de dépense de révocation du signet spend_revoke.
  4. Clé privée de scan de révocation du signet scan_revoke.
  5. Clé privée de dépense mainnet spend_mainnet.
  6. Clé privée de scan du mainnet scan_mainnet.

8.1. Descripteurs de wallet

Les descripteurs de wallet sont une méthode standardisée pour décrire les scripts que le wallet peut utiliser pour dépenser des bitcoins. Ils fournissent une manière compacte et compréhensible de représenter les scripts, incluant les informations sur le type d'adresse (par exemple, P2PKH, P2SH, P2WPKH, etc.), et les clés ou chemins de clés impliqués.

wpkh([cprv1/44'/1'/0'/0/0]spend_recover) # cprv1 pour la clé privée `spend_recover`
wpkh([cprv2/44'/1'/0'/0/1]scan_recover)  # cprv2 pour la clé privée `scan_recover`
wpkh([cprv3/44'/1'/0'/0/2]spend_revoke)  # cprv3 pour la clé privée `spend_revoke`
wpkh([cprv4/44'/1'/0'/0/3]scan_revoke)   # cprv4 pour la clé privée `scan_revoke`

wpkh([cprv5/84'/0'/0'/0/0]spend_mainnet) # cprv5 pour la clé privée `spend_mainnet`
wpkh([cprv6/84'/0'/0'/0/1]scan_mainnet) # cprv6 pour la clé privée `scan_mainnet`

Ici, wpkh signifie "witness public key hash" (SegWit), [clé_priveN/84'/M'/0'/0/n] est le chemin de dérivation avec N la référence à la clé privée, M est 1 pour signet custom (normalement 1 représenterait testnet, mais un signet custom peut avoir une convention différente) et 0 pour mainnet, n est l'index de l'adresse, et xpubN représente l'extended public key correspondant à la clé privée. Le /0/* à la fin indique que ce sont des adresses de réception (change addresses seraient /1/*).

Ici, cprvN représente un placeholder pour le chemin de dérivation de chaque clé privée. Les clé_priveN sont des placeholders pour les clés privées réelles, et le reste de la structure reste comme expliqué précédemment.

Ici il s'agit du format de stockage des privées, ce pourquoi la clé privée est indiquée dans le descripteur au lieu de la xpub plus classiquement utilisées pour ne pas exposer les clés privées.

8.2. Récupération des jetons de faucet

Le relais retournent des jetons à la connexion et à l'envoi de messages afin de créer les UTXO nécessaires pour les transactions SP.

Pour revoir ces jetons l'utilisateur doit générer les adresses sur lesquelles il souhaite recevoir les jetons.

A chaque nouveau message il génère de nouvelles addresses pour la clé qui va dépenser des jetons de signet. Soit une nouvelle adresse (publique) de la clé privée spend_recover.

Ces adresses apparaîtront dans l'attribut faucet_sp_address des messages envoyés aux relais.

9. Gestion des clés de l'identité (aussi les clés des transactions SP)

9.1. Génération des clés privées (création des identités numériques)

9.1.1. Gestion de la clé servant à l'ID spend_recover

Les clés font 256 bits.

La clé privée spend_recover est la clé principale pour forger les identités.

Cette clé est d'abord décomposée, avant d'être partiellement distribuée. Voici les principales étapes :

  1. Cette clé sera scindée en 2 parties (à la moitié de la longueur de leur représentation hexadécimale) :

    1.1. Part1, de 128 bits c'est la partie qui sera chiffrée (AES-GCM 256 bits) par le mot de passe "hashé" (SHA-256) pour seed de 256 bits et stockée en cache dans une image dite de login. En fonction des cas d'usage le mot de passe peut être remplacé par une seed de 256 bits directement et de meilleure entropie que le mot de passe.

    1.2. Part2, de 128 bits, c'est la partie qui sera chiffrée (AES-GCM 256 bits) par le mot de passe "hashé" (SHA-256) pour seed de 256 bits et sera répartie par un Shamir Secret Sharing, chiffrée pour chaque partie par le mot de passe et distribuées en 1 pour 1 aux membres actuels du rôle de gestionnaire des membres du ItemProcess. En fonction des cas d'usage le mot de passe peut être remplacé par une seed de 256 bits directement et de meilleure entropie que le mot de passe.

  2. Une pre-id Part1EncHash qui identifie l'utilisateur est générée par le hash (SHA 256) de la Part1 et du mot de passe de l'utilisateur.

  3. Création d'un RequestPrdKeyBackup par membre (1 shard par membre), par RequestPrd :

    3.1. Génération d'une clé de chiffrement dite sp_shared_secret qui sera transmise dans le Diffie-Hellman de la transaction SP.

    3.2. Définition de l'attribut device_footprint_enc_by_sp_shared_secret et chiffrement avec sp_shared_secret.

    3.3. Définition de l'attribut pre_id_enc_by_sp_shared_secret et chiffrement avec sp_shared_secret.

    3.4. Définition de l'attribut shard_enc_by_sp_shared_secret et chiffrement avec sp_shared_secret.

  4. Création des messages de type Message correspondant aux RequestPrd, envoi des messages aux relais connectés.

Dans l'ordre on réalise donc les opérations suivantes donc :

  1. Split de spend_recover.
  2. Chiffrement AES de Part1.
  3. Mise en cache de Part1Enc.
  4. Création de la pre-id
  5. Chiffrement AES de Part2.
  6. Sharding de Part2Enc.

9.1.2. Backup de Part2Enc

Les relais initialisent le SDK (Wasm) par défaut avec une liste SharedProcessList de SharedProcess contenant les membres du rôle member du ItemProcess choisi.

Chacun de ses membres sera responsable de d'associer un shard de Part2Enc à une pre-id et de revoyer des les shards dans un RequestPrdResponse en réponse à un RequestPrdKeyBackup.

Dans l'ordre on réalise donc les opérations suivantes pour chaque membres :

  1. Création de RequestPrdKeyBackup à destination du membre
  2. Création de Message du RequestPrdKeyBackup à destination du membre.
  3. Envoi de la transaction SP du Message du RequestPrdKeyBackup à destination du membre.
  4. Envoi du Message du RequestPrdKeyBackup à destination du membre.
  5. Atttente de la réception des RequestPrdResponse en réponse aux RequestPrdKeyBackup (confirmations).
  6. Recomposition de la clé pour confirmation depuis les shards reçus dans les RequestPrdResponse. 6.1. Déchiffrement par le mot de passe de Part1Enc depuis le cache. 6.2. Déchiffrement par secret partagé de chaque shard reçu dans id_shard_info_enc_by_shared_secret des RequestPrdResponse de chaque member du role Memberdu ItemProcess. 6.3. Recomposition de Part2Enc et déchiffrement par le mot de passe 6.4. Concaténation de Part1 et Part2
Étape d'update et envoi de l'objet ItemMember pour Onboarding

Pour être onboard dans un process, c'est-à-dire avoir un rôle, il faut :

  1. s'ajouter (objet Member) dans la liste des membres et
  2. s'ajouter son adresse SP dans les adresses d'un des rôles du ItemProcess.
Mise à jour de la liste des membres

Pour mettre à jour la liste des membres il faut envoyer un RequestPrdUpdate avec une nouvelle version du RequestPcd de la liste des membres, contenant l'objet ItemMember complet aux membres du role member. Ce RequestPrd devra recevoir des membres du rôle Member du ItemProcess les RequestPrdResponse correspondant aux critères de validation du ItemProcess .

C'est à ce moment-là que l'on transmet toutes les clés privées dans l'objet ItemMember, en tant que metadadata privée (chiffrée par la clé de dépense du signet) dans un RequestPcd (et les RequestPrdUpdate correspondant).

Les adresses SP correspondantes sont aussi transmises en tant que données publiques, ainsi que l'adresse SP de la clé de dépense du login du signet.

Les metadatas des membres propres au ItemProcess sont décrits dans le ItemProcess et doivent compléter les metadatas de l'ItemMember.

L'ItemMember est décrit dans la spécification Specs-Datamodel.md.

  1. Création d'un ItemMember correspondant à l'utilisateur.
  2. Création d'une nouvelle version du RequestPcd avec l'ajout de l'ItemMember créé.
  3. Création de RequestPrdKeyHello à destination du membre.
  4. Création de Message du RequestPrdKeyHello à destination du membre.
  5. Envoi de la transaction SP du Message du RequestPrdKeyHello à destination du membre.
  6. Envoi du Message du RequestPrdKeyHello à destination du membre.
  7. Réception des RequestPrdResponse en réponse aux RequestPrdKeyHello et mise à jour des listes depuis les RequestPcd correspondants.
  8. Attente de la validation (RequestPrdResponse) du RequestPrdUpdate.
Mise à jour de la liste des process

Pour mettre à jour la liste des ItemProcess il faut envoyer un RequestPrdUpdate avec une nouvelle version du RequestPcd de la liste des process, contenant l'objet ItemProcess complet aux membres du role ItemProcess . Ce RequestPrd devra recevoir des membres du rôle ItemProcess du ItemProcess les RequestPrdResponse correspondant aux critères de validation du ItemProcess .

L'ItemProcess est décrit dans la spécification Specs-Datamodel.md.

Demande d'update de la liste des membres ( RequestPcd) d'un ItemProcess vers chaque membre du rôle Member du ItemProcess.:

  1. Création d'un ItemProcess correspondant à l'utilisateur.
  2. Création d'une nouvelle version du RequestPcd avec l'ajout de l'ItemProcess créé.
  3. Création de RequestPrdKeyHello à destination du membre.
  4. Création de Message du RequestPrdKeyHello à destination du membre.
  5. Envoi de la transaction SP du Message du RequestPrdKeyHello à destination du membre.
  6. Envoi du Message du RequestPrdKeyHello à destination du membre.
  7. Réception des RequestPrdResponse en réponse aux RequestPrdKeyHello et mise à jour des listes depuis les RequestPcd correspondants.
  8. Attente de la validation (RequestPrdResponse) du RequestPrdUpdate.
  9. Redirection vers la page du ItemProcess sur le relai.
Clés de révocation (revoke)

Les clés de l'image de révocation sont chiffrées par le mot de passe (ou pas, en option) et stockées directement dans les données exifs de l'image de révocation. Les adresses SP correspondantes sont aussi inscrites dans les données exif.

L'envoi d'une révocation est identique à la création d'une nouvelle adresse via les RequestPrdKeyBackup mais la transaction SP est envoyée depuis l'adresse de révocation (la clé aura dû être chargée au préalable depuis l'interface).

Clés de third parties

Au moment de l'update de l'ItemMember il est possible de charger des addresses SP de third parties pour lesquelles l'utilisateur a un rôle dans un ItemProcess. Ces adresses sont ajoutées avec les labels et éventuellement les empreintes des dispositifs correspondants dans l'objet ItemMember.

Les clés privées associées sont générées lors de l'update d'un membre, à la validation de l'update il est possible de télécharger des images correspondantes (clés + hash du process) dans une interface 2FA.

Lorsqu'une transaction est reçue sur l'application de 2FA, celle-ci demande de confirmer ou non. Si il y a une confirmation dans l'interface alors une transaction SP est envoyée au dispositif initial, en dépensant l'UTXO reçue et avec les mêmes Hash dans les outputs que la transaction reçue afin que le dispositif initial puisse collecter les RequestPrd concernés.

9.1.3. Connexions avec une identité crée (recover)

Pour recrééer sa clé privée et envoyer un RequestPrdKeyHello à chaque membre du rôle Member du process, il faut réaliser les opérations suivantes :

  1. Récupération de Part1Enc en cache
  2. Création de la pre_id avec le mot de passe

Puis depuis la liste des membres du process, pour chacun des membres :

  1. Création de RequestPrdKeyHello à destination du membre 1.
  2. Création de Message du RequestPrdKeyHello à destination du membre.
  3. Envoi de la transaction SP du Message du RequestPrdKeyHello à destination du membre.
  4. Envoi du Message du RequestPrdKeyHello à destination du membre.
  5. Attente de la validation (RequestPrdResponse) du RequestPrdUpdate.
  6. Recomposition de la clé pour confirmation depuis les shards reçus dans les RequestPrdResponse. 6.1. Déchiffrement par le mot de passe de Part1Enc depuis le cache. 6.2. Déchiffrement par secret partagé de chaque shard reçu dans id_shard_info_enc_by_shared_secret des RequestPrdResponse de chaque member du role Memberdu ItemProcess. 6.3. Recomposition de Part2Enc et déchiffrement par le mot de passe 6.4. Concaténation de Part1 et Part2

Demande d'update de la liste des membres ( RequestPcd) d'un ItemProcess :

  1. Création et envoi des RequestPrdList.
  2. Réception des RequestPrdResponse en réponse aux RequestPrdList et mise à jour des listes depuis les RequestPcd correspondants.
  3. Création d'un ItemMember correspondant à l'utilisateur avec les clés chiffrées (hors clés de révocation) dans la partie data des métadonnées privées et les adresses SP dans les données publiques.
  4. Création d'une nouvelle version du RequestPcd avec l'ajout de l'ItemMember créé.
  5. Redirection vers la page du ItemProcess sur le relai.

10. Exemples de Code

11. Todo

  • Extraits de code illustrant l'utilisation des RequestPcd et RequestPrd dans des scénarios réels.
  • Diagrammes de séquences