Discourse Encrypt (veraltet)

Original Plugin-Beschreibung
:discourse2: Zusammenfassung Discourse Encrypt ermöglicht private, verschlüsselte Nachrichten zwischen Endbenutzern. Alle sensiblen Informationen werden sicher auf dem Server gespeichert und nur auf der Client-Seite verschlüsselt und entschlüsselt.
:hammer_and_wrench: Repository-Link https://github.com/discourse/discourse-encrypt
:open_book: Installationsanleitung So installieren Sie Plugins in Discourse

Drei einfache Schritte zur Verwendung dieses Plugins

  1. Verschlüsselung aktivieren und aktuelles Gerät aktivieren.

  1. Eine verschlüsselte Nachricht senden. Der Empfänger muss ebenfalls die Verschlüsselung aktiviert haben.

Optional können Sie die Zeit festlegen, nach der die gesamte Nachricht oder ein bestimmter Beitrag dauerhaft gelöscht wird.

  1. Geheime Nachrichten lesen. Die Verschlüsselung muss zuerst aktiviert sein, um sie lesen zu können.

Hinweis: In diesem Beispiel wurde der Benutzer erneut nach dem Papier-Schlüssel gefragt, da die Verschlüsselung deaktiviert wurde (durch Abmelden oder explizites Deaktivieren im Einstellungsbildschirm).

Technische Informationen

Dieses Plugin bietet Benutzern die Möglichkeit, über Discourse sicher zu kommunizieren, indem ein End-to-End-Verschlüsselungsverfahren verwendet wird. Der Großteil der Plugin-Logik wird auf der Client-Seite implementiert, und der Server verarbeitet nur öffentliche oder verschlüsselte Informationen. Es werden keine Metadaten von Beiträgen verschlüsselt, wie z. B. Namen der Teilnehmer im Gespräch, Zeitpunkt des Postens, Likes, kleine Aktionen usw.; Uploads werden verschlüsselt, aber ihre Existenz nicht, da das System Uploads mit Beiträgen verknüpfen muss, um deren Löschung zu verhindern.

Der gesamte Code ist Open-Source, und Sicherheitsenthusiasten sind willkommen, ihn zu überprüfen. Für weitere Informationen zögern Sie nicht, mich oder das Team zu kontaktieren. :slight_smile:

mehr lesen...

Zusammenfassung

Das Ziel dieses Plugins ist es, Integrität und Vertraulichkeit der verschlüsselten Inhalte zu gewährleisten und sie vor Informationslecks und unbefugten Benutzern zu schützen. Die folgenden Abschnitte beschreiben den üblichen Betriebsmodus, verwendete Algorithmen und Bedrohungsmodelle.

Um dieses System zu verwenden, registrieren sich Benutzer einmalig, indem sie eine „Benutzeridentität“ generieren, die aus zwei 4096-Bit-RSA-Schlüsseln besteht, einem für die Verschlüsselung und einem für die Signatur. Benutzer können ihre „Identität“ zur sicheren Aufbewahrung exportieren oder auf dem Server speichern, nachdem sie einen Papier-Schlüssel generiert haben. Diese beiden Methoden dienen als Sicherungskopien oder werden zur Registrierung neuer Geräte verwendet.

Papier-Schlüssel (inspiriert von RFC 1751 und BIP-39) sind menschenlesbare Schlüssel, die verwendet werden, um die „Benutzeridentität“ sicher auf dem Server zu speichern. Ein Papier-Schlüssel besteht aus 12 zufälligen Wörtern, die aus einer Liste von 2048 Wörtern ausgewählt werden, und bietet 121-Bit-Entropie (das erste Wort wird als Beschriftung verwendet). Um die „Benutzeridentität“ mit einem Papier-Schlüssel zu verschlüsseln, leitet das System zunächst den Verschlüsselungsschlüssel mithilfe von PBKDF2 ab, um den Papier-Schlüssel in einen 256-Bit-AES-GCM-Schlüssel zu strecken.

Erstellen eines verschlüsselten Beitrags

Um einen neuen Beitrag zu erstellen, führt der Benutzer (sein Browser) folgende Schritte aus:

  1. Signieren Sie den aktuellen Beitrag mit Ihrem privaten Signierschlüssel;

  2. Generieren Sie einen neuen „Topic-Schlüssel“ (einen AES-256-GCM-Schlüssel) – dieser wird verwendet, um den Beitrag, einige Beitragsmetadaten und den Titel des neuen Topics (falls verfügbar) zu verschlüsseln;

  3. Holen Sie sich die öffentlichen Schlüssel aller Teilnehmer und verschlüsseln Sie den „Topic-Schlüssel“ für jeden von ihnen;

  4. Senden Sie den verschlüsselten Beitrag (Base64-kodiert) und die verschlüsselten Topic-Schlüssel (ebenfalls Base64-kodiert) jedes Teilnehmers an den Server.

Der Pseudocode für den Verschlüsselungsvorgang könnte wie folgt aussehen:

signature = rsa_pss_sign(current_user.identity.sign_key.private, post.raw) # 1
topic_key = topic.key || generate_aes_256_gcm_key() # 2
encrypted_title = aes_256_gcm_encrypt(topic.title, topic_key) if topic.blank?
encrypted_post = aes_256_gcm_encrypt(signature + post.raw, topic_key)
encrypted_topic_keys = recipients.map { |r| rsa_oaep_encrypt(topic_key, r.identity.encryption_key.public) } # 3
$.put("/posts/create", { title: encrypted_title, raw: encrypted_post, keys: encrypted_topic_keys }) # 4

Lesen eines verschlüsselten Beitrags

Um einen Beitrag zu lesen, führt der Benutzer (sein Browser) folgende Schritte aus:

  1. Holen Sie sich den verschlüsselten Beitrag (Beitragstext und Signatur) und den verschlüsselten Topic-Schlüssel;

  2. Verwenden Sie Ihren privaten Verschlüsselungsschlüssel, um den verschlüsselten Topic-Schlüssel zu entschlüsseln;

  3. Verwenden Sie den entschlüsselten Topic-Schlüssel, um den verschlüsselten Beitragstext zu entschlüsseln;

  4. Holen Sie sich den öffentlichen Signierschlüssel des Autors und überprüfen Sie die Beitragssignatur.

Algorithmus-Suite

Dieses Plugin verwendet intensiv die kryptografischen Primitive, die in der Web Crypto API implementiert sind, die in allen modernen Browsern verfügbar sind, die Discourse unterstützt (außer Internet Explorer).

  • getRandomValues PRNG: Generiert Papier-Schlüssel und 96-Bit-zufällige IVs.

  • PBKDF2: Streckt die 132-Bit-Papier-Schlüssel auf 256-Bit-Schlüssel, die zum Verschlüsseln von „Benutzeridentitäten“ verwendet werden.

  • AES-256-GCM: Wird verwendet, um den Inhalt jedes Beitrags zu verschlüsseln. Es bietet auch Authentifizierung durch Erstellen eines 128-Bit-Authentifizierungstags, aber dies ist ein weniger wichtiger Aspekt, da Beiträge mit einer Signatur des Autors überprüft werden (siehe Schritt 1 oben).

  • RSA-OAEP: Wird verwendet, um „Topic-Schlüssel“ und „Benutzeridentitäten“ zur sicheren Aufbewahrung auf dem Server zu verschlüsseln. Alle RSA-OAEP-Schlüssel sind 4096-Bit lang.

  • RSA-PSS: Wird verwendet, um den Inhalt jedes Beitrags zu signieren, um die Authentizität zu überprüfen. Alle RSA-PSS-Schlüssel sind 4096-Bit lang.

Primitive

Das System verwendet eine Reihe von Primitiven, die auf denen aufbauen, die vom Browser über die Web Cryptography API bereitgestellt werden.

  • encrypt und decrypt: Wird verwendet, um Beitragsinhalte zu verschlüsseln und zu entschlüsseln. encrypt nimmt ein JSON, einen AES-256-GCM-Schlüssel und einen RSA-PSS-öffentlichen Schlüssel entgegen und gibt einen einzelnen Base64-kodierten String zurück; decrypt nimmt einen Base64-kodierten String und einen AES-256-GCM-Schlüssel entgegen und gibt das ursprüngliche JSON-Objekt zurück;

  • verify: Wird verwendet, um Beitragsinhalte nach der Entschlüsselung zu überprüfen;

  • exportKey und importKey: Wird verwendet, um „Topic-Schlüssel“ zu exportieren und zu importieren;

  • exportIdentity und importIdentity: Wird verwendet, um „Benutzeridentitäten“ zu exportieren und zu importieren.

Arten von Schlüsseln:

  • Topic-Schlüssel (AES-256-GCM)

    • werden verwendet, um jeden Beitrag in einem Topic zu verschlüsseln (Beiträge werden einzeln verschlüsselt)
    • werden generiert pro Topic auf der Client-Seite vom ursprünglichen Autor unter Verwendung der WebCrypto-API generateKey-Primitive
    • werden mit dem öffentlichen Schlüssel des Benutzers für jeden Benutzer verschlüsselt, der Zugriff auf das spezifische Topic hat, unter Verwendung der WebCrypto-API wrapKey-Primitive
    • werden gespeichert (verschlüsselt) auf der Server-Seite für jeden Benutzer in PluginStore
  • RSA-Schlüsselpaar (öffentlicher und privater Schlüssel) (RSA-OAEP und RSA-PSS, 4096-Bit)

    • werden verwendet, um alle Topic-Schlüssel zu verschlüsseln, auf die ein Benutzer Zugriff hat
    • werden generiert pro Benutzer auf der Client-Seite vom ursprünglichen Autor unter Verwendung der WebCrypto-API generateKey-Primitive und zwischen allen Geräten des Benutzers geteilt
    • serverseitig: Die öffentliche Identität wird so gespeichert, wie sie vom Client exportiert wurde, aber die private Identität wird immer mit dem Passphrasenschlüssel verschlüsselt
    • clientseitig: Öffentlicher und privater Schlüssel werden als CryptoKey in IndexedDb gespeichert; falls nicht möglich, wird window.localStorage verwendet (in Safari)
  • Passphrasenschlüssel (abgeleitet unter Verwendung von PKBDF2 mit 128.000 Iterationen)

    • werden verwendet, um „Benutzeridentitäten“ zur sicheren Speicherung auf dem Server zu verschlüsseln
    • abgeleitet aus einem Papier-Schlüssel (oder dem Passwort des Benutzers aus historischen Gründen)

Bedrohungsmodelle

Kompromittierte Discourse-Instanz

Ein Angreifer, der Code injizieren kann, könnte theoretisch auf verschlüsselte Informationen zugreifen, indem er bösartigen Code bereitstellt, der den verschlüsselten Inhalt entschlüsselt und die Klartext-Beiträge an einen anderen Server sendet. Um dies zu ermöglichen, reicht es aus, Zugriff auf ein Administratorkonto zu haben und eine Theme-Komponente mit dem bösartigen Code zu erstellen.

Standard-Schutzmechanismen wie CSP können Cross-Site-Scripting-Angriffe (XSS) erkennen und mildern, die ebenfalls eine Möglichkeit zur Injektion von bösartigem Code darstellen könnten.

Man-in-the-Middle-Angriff

Bei Man-in-the-Middle-Angriffen fängt der Angreifer die Kommunikation zwischen Benutzer und Server ab und hat dadurch die Möglichkeit, sie zu lesen oder zu verändern. Da das Plugin alles vor dem Senden verschlüsselt, kann ein Angreifer durch einfaches Abhören nichts entschlüsseln. Ebenso kann der Angreifer aufgrund der Authentifizierung der Informationen nichts verändern.

Der Angreifer könnte jedoch bösartigen Code an den Benutzer zurücksenden und einen ähnlichen Angriff wie im vorherigen Abschnitt durchführen. Dies wird teilweise durch HTTPS gemildert, was die Angriffswahrscheinlichkeit erheblich reduziert.

Hinweise

Das Plugin hat bereits eine kleine Geschichte, die beim Durchsuchen des Quellcodes und beim Erkennen der beiden Implementierungen des Protokolls v0 (initial, Alpha-Beta-Version) und v1 sichtbar wird. Das Protokoll v0 wird nicht mehr zum Verschlüsseln neuer Beiträge verwendet, aber beibehalten, um alte Beiträge weiterhin entschlüsseln zu können. Das neue Protokoll umfasst die Authentizität der Chiffretexte, und alle Beiträge werden mit dem privaten Schlüssel des Autors signiert.

Weitere Ressourcen

99 „Gefällt mir“
PMs are accesible by admins if the admin has the link
Are PMs truly private and not crawlable?
Can true private messages be implemented?
What to do if your Discourse is compromised
Notifications but not emails
Possible privacy flaw with DMs
Encrypted PGP Messaging
Spoiler for certain user groups?
End-to-end Encryption for Chat
Preserving user sessions when migrating between hosts
Make MP's actually private
Generate Paper Key?
Add a warning when checking personal messages from a user public profile, as an admin
Types of community & their characteristics
What personal data is collected and who can read/edit it?
We still have Discourse Encrypt plugin - Would running community updates cause any issues?
Matrix protocol for chat
Can you edit the admin menu?
Discourse Encrypt breaks replies on latest Discourse update
Upload not working in encrypted private message?
E-Mail Preview Summary: wrong number of arguments (given 10, expected 1)
When you started your first Discourse community, what did you find hard to do?
Search in Encrypted messages, like in ProtonMail or Wire
No backup warn link issue
How can a group have end-to-end encryption
Images disapper from the Builder Preview in encrypted message drafts after page reload
Is there anyway to change ‘secret’ to secure?
Can someone explain `post metadata was updated without being signed again`?
Encrypt plug-in issue
Generate Paper Key?
Can't activate encrypted messages on my phone - says my paper key is incorrect or the key pair is incorrect
Search engines and private messages?
TypeError: Cannot set property deleteTopic of [object Object] which has only a getter
PMs are accesible by admins if the admin has the link
Can Discourse function without emails entirely?
Discourse Encrypt breaks replies on latest Discourse update
Admins can see private messages in user's profiles?
Thoughts on Turning Off Personal Messaging and Chats
Spoiler but only admins can see it
Account creation not working with discourse_encrypt
Strategies for Isolating Plugin Secrets in Discourse
Disable watched words / censor in personal messages
Cannot Delete or Rotate Encryption Keys
How alert if admin/mods read users PM?
How alert if admin/mods read users PM?
Can we prevent an admin from seeing a private category?