Nous souhaitons commander un plugin permettant la messagerie privée et chiffrée entre les utilisateurs finaux.
Ce plugin existe désormais et est officiellement pris en charge, consultez Discourse Encrypt (deprecated)
À l’heure actuelle, il existe très peu de plateformes en ligne pour une communication longue, sécurisée et privée. Les outils existants sont généralement assez obscurs et nécessitent des compétences techniques extrêmes pour être utilisés. Par conséquent, la majorité des communications “privées” se font de manière “courte” sur Telegram, Skype ou WhatsApp. De plus, ce mode de communication de masse n’est pas correctement auditable car il repose sur des outils propriétaires et souvent sur des protocoles fermés.
Nous souhaitons développer une solution hautement utilisable et auditable pour la messagerie chiffrée dans un plugin dédié à Discourse.
Pour y parvenir, nous souhaitons nous appuyer sur quelques principes :
-
Construire la solution sur l’API Web Crypto.
-
Faire en sorte que le serveur stocke une clé privée chiffrée et une clé publique par utilisateur.
-
Faire en sorte que le serveur stocke une clé de conversation chiffrée par participant aux messages privés (chiffrée à l’aide de la clé privée de l’utilisateur final).
-
Stocker tout le Markdown et les titres sous forme brute et chiffrée pour chaque message (chiffré à l’aide de la clé de conversation).
-
Accepter la limitation selon laquelle le serveur sait qui a parlé à qui et quand (nous ne protégeons que le “quoi”). Accepter la limitation selon laquelle la recherche ne fonctionnera pas pour ce contenu.
Expérience utilisateur proposée
Jane se rend sur sa page utilisateur et clique sur le bouton “activer la messagerie chiffrée”. Une fois cliqué, elle est invitée à saisir un secret. L’interface explique clairement que si elle oublie ce secret, elle n’aura JAMAIS à nouveau accès à ses messages chiffrés.
Une fois la messagerie chiffrée activée, une nouvelle case [ ] apparaîtra dans l’interface de création de message avec le texte [ ] chiffrer le message. Cette case ne sera cliquable que si tous les destinataires ont l’option “activer la messagerie chiffrée” activée. Si certains n’ont pas de clés publiques, lorsque nous tenterons de cliquer dessus, nous afficherons : “Désolé, mais certains participants n’ont pas activé la messagerie chiffrée”.
Jane décide qu’elle souhaite parler en privé à Pete. Elle l’ajoute à la liste des participants, clique sur chiffrer le message et envoie un message à Pete.
Pete reçoit une notification indiquant que Jane lui a envoyé un message chiffré. Il n’y a pas de titre, juste l’information qu’un message chiffré existe, avec des liens vers le message (à la fois dans la notification par e-mail et dans la notification web).
Si Pete est sur l’appareil original où il a activé la messagerie chiffrée, sa phrase secrète a déjà été saisie et les identifiants sont déjà stockés dans IndexedDB. Si Pete est sur un nouvel appareil, il sera invité à saisir sa phrase secrète pour activer la messagerie chiffrée.
L’interface affiche clairement une superposition ou un indice visuel pour indiquer que le message est chiffré.
Une fois la communication initiée entre Jane et Pete, l’un ou l’autre peut inviter de nouvelles personnes au message, à condition qu’elles disposent de clés publiques.
Pete ou Jane peuvent modifier leur phrase secrète quand ils le souhaitent. Dans ce cas, la clé privée sera re-chiffrée avec la nouvelle phrase secrète et envoyée au serveur. (Pour la version 1, nous ne permettrons pas de modifications de la clé privée elle-même, seulement de la phrase secrète).
Détails techniques
À aucun moment, aucune conversation privée non chiffrée ni aucune identité de connexion privée ne sera envoyée au serveur. La seule confiance accordée au serveur est que personne n’a altéré le chargeur JavaScript envoyé au client.
Les paires de clés privées et publiques seront générées à 100 % côté client, puis la clé privée sera chiffrée à l’aide du chiffrement symétrique AES avant d’être remise au serveur pour sauvegarde. Nous étirerons la phrase secrète à l’aide d’un sel généré aléatoirement et stocké sur le serveur. L’étirement de la clé sera effectué côté client à l’aide de PBKDF2 (disponible dans l’API Web Crypto). La paire de clés privée/publique sera stockée côté client dans IndexedDB en utilisant un objet CryptoKey non exportable. Les données CryptoKey exportables seront supprimées de la mémoire dès que possible.
La clé privée chiffrée et la clé publique seront stockées dans des champs personnalisés d’utilisateur. Seul current_user sera autorisé à lire/écrire la clé privée chiffrée ; tous les utilisateurs connectés seront autorisés à lire les clés publiques de tous les utilisateurs.
Les clés de conversation seront générées côté client lors du début de la conversation ou d’une invitation, puis chiffrées à l’aide de toutes les clés publiques impliquées dans la conversation. Ces données seront stockées dans une table dédiée (user_id, topic_id, encrypted_conversation_key). Cette ligne sera créable par n’importe quel utilisateur de la conversation, mais ne sera lisible que par current_user == user_id.
Des précautions spéciales seront prises pour ne jamais divulguer de données non chiffrées au serveur, ce qui inclut s’assurer que les brouillons ne sont pas stockés en clair.
Pour éviter une grande classe d’erreurs, de nouveaux éléments DOM (avec de nouveaux identifiants) seront utilisés pour l’édition et l’aperçu du compositeur. L’actuelle .d-editor-input ne contiendra que des blobs chiffrés et l’aperçu traditionnel sera désactivé. (ce qui signifie que deux zones de texte seront en jeu : chiffrée et non chiffrée). Le chiffrement sera fortement désactivé (debounced) pour éviter une classe de problèmes de performance.
Pour la version 1 (et la portée de cette tâche), nous sommes prêts à éliminer certaines fonctionnalités, notamment le support des téléchargements, le oneboxing du contenu chiffré et d’autres cas complexes.
Nous acceptons de déchiffrer, de compiler et de faire passer le HTML à travers un whitelisteur à la volée lors du rendu de ce contenu privé.
Exigences de documentation
Avant la mise en œuvre, une spécification très détaillée sera créée, incluant des maquettes web et, surtout, un aperçu de sécurité détaillé.
Exigences de test
Ce plugin doit inclure un ensemble complet de tests unitaires et d’intégration basés sur le client et le serveur. Si vous prenez ce projet en charge, écrivez des tests dès le début ; n’attendez pas la fin du projet pour ajouter des tests.
Préoccupations
La plupart des préoccupations soulevées dans : https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/ ne sont plus pertinentes étant donné l’API Web Crypto (génération de bytes aléatoires véritables, stockage de clés privées, et la liste est longue). Le seul vecteur majeur qui existe est le serveur envoyant au client du JavaScript malveillant. À court terme, les utilisateurs seront simplement censés faire confiance au serveur, tout comme ils font confiance à 1Password, LastPass et autres interfaces de sécurité web. À plus long terme (v3/v4 - l’année prochaine ou après), nous pourrons envisager de publier une extension de navigateur qui place un cadenas sur les sites où tous les hachages de stabilité des chargeurs JS sont bien connus.
L’API WebCrypto est encore relativement jeune mais assez largement prise en charge ; le plugin doit fonctionner sur tous nos navigateurs pris en charge.
Maquettes simples et approximatives
* Lors du début d’un message, l’utilisateur peut choisir de chiffrer la conversation ; un avertissement sera affiché si l’un des participants manque de clés publiques.
* Les utilisateurs peuvent activer les messages chiffrés en cliquant sur ce bouton et en suivant une interface qui génère la paire de clés.
Si les messages chiffrés sont activés, l’interface devrait simplement afficher : “Vous avez activé la messagerie chiffrée”.
* Une sorte d’icône ou de superposition indiquera qu’un message est chiffré.
Budget
Il s’agit d’une pièce très complexe à construire, nécessitant une intégration très approfondie et un examen attentif. Nous nous attendons à ce qu’elle soit extrêmement bien testée (en utilisant à la fois des tests côté client et côté serveur). Notre budget actuel pour un MVP est de 10 000 USD.


