Discourse Encrypt (descontinuado)

Descripción original del plugin
:discourse2: Resumen Discourse Encrypt habilita mensajes privados y cifrados entre usuarios finales. Toda la información sensible se almacena de forma segura en el servidor y solo se cifra y descifra en el lado del cliente.
:hammer_and_wrench: Enlace al repositorio https://github.com/discourse/discourse-encrypt
:open_book: Guía de instalación Cómo instalar plugins en Discourse

Tres pasos sencillos para usar este plugin

  1. Habilita el cifrado y activa el dispositivo actual.

  1. Envía un mensaje cifrado. El destinatario también debe haber habilitado el cifrado.

Opcionalmente, puedes determinar el tiempo después del cual todo el mensaje o una publicación específica será destruido permanentemente.

  1. Lee mensajes secretos. El cifrado debe estar activado primero para poder leerlos.

Nota: En este ejemplo, se le pidió al usuario la clave en papel nuevamente porque el cifrado se desactivó (al cerrar sesión o desactivarlo explícitamente desde la pantalla de preferencias).

Información técnica

Este plugin ofrece a los usuarios la posibilidad de comunicarse de forma segura a través de Discourse, utilizando un esquema de cifrado de extremo a extremo. La mayor parte de la lógica del plugin se implementa en el lado del cliente y el servidor solo maneja información pública o cifrada. No cifra ningún metadato de la publicación, como los nombres de los participantes en la conversación, la hora de publicación, los «me gusta», las pequeñas acciones, etc.; las subidas están cifradas, pero su presencia no lo está porque el sistema debe asociar las subidas con las publicaciones para evitar eliminarlas.

Todo el código es de código abierto y los entusiastas de la seguridad son bienvenidos a revisarlo. Para cualquier información adicional, no dudes en contactarme o al equipo. :slight_smile:

leer más...

Resumen

El objetivo de este plugin es ofrecer integridad y confidencialidad a los contenidos cifrados, y protegerlos contra fugas de información y usuarios no autorizados. Las siguientes secciones describen el modo de operación habitual, los algoritmos utilizados y los modelos de amenazas.

Para usar este sistema, los usuarios se registran una vez generando una «identidad de usuario» que consta de dos claves RSA de 4096 bits, una para cifrado y otra para firma. Los usuarios pueden exportar su «identidad» para guardarla de forma segura o almacenarla en el servidor, cifrada después de generar una clave en papel. Estos dos métodos sirven como copias de seguridad o se utilizan para registrar nuevos dispositivos.

Las claves en papel (inspiradas en RFC 1751 y BIP-39) son claves legibles por humanos que se utilizan para almacenar de forma segura la «identidad de usuario» en el servidor. Una clave en papel consta de 12 palabras aleatorias, seleccionadas de una lista de 2048 palabras, que ofrecen 121 bits de entropía (la primera palabra se usa como etiqueta). Para cifrar la «identidad de usuario» con una clave en papel, el sistema primero derivará la clave de cifrado utilizando PBKDF2 para estirar la clave en papel en una clave de 256 bits AES-GCM.

Crear una publicación cifrada

Para crear una nueva publicación, el usuario (su navegador) hará lo siguiente:

  1. firmar el contenido de la publicación actual utilizando su clave de firma privada;

  2. generar una nueva «clave de tema» (una clave AES-256-GCM) que se utilizará para cifrar la publicación, algunos metadatos de la publicación y el título del nuevo tema (si está disponible);

  3. obtener las claves públicas de todos los participantes y cifrar la «clave de tema» para cada uno de ellos;

  4. enviar al servidor la publicación cifrada (codificada en Base64) y las claves de tema cifradas (también codificadas en Base64) de cada participante.

El pseudocódigo para la operación de cifrado sería algo así:

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

Leer una publicación cifrada

Para leer una publicación, el usuario (su navegador) hará lo siguiente:

  1. obtener la carga útil de la publicación cifrada (texto plano de la publicación y firma) y la clave de tema cifrada;

  2. usar su clave de cifrado privada para descifrar la clave de tema cifrada;

  3. usar la clave de tema descifrada para descifrar la carga útil de la publicación cifrada;

  4. obtener la clave de firma pública del autor y verificar la firma de la publicación.

Suite de algoritmos

Este plugin hace un uso extensivo de los primitivos criptográficos implementados en la API Web Crypto, que están disponibles en cualquier navegador moderno que Discourse admite (excepto Internet Explorer).

  • getRandomValues PRNG: Genera claves en papel e IVs aleatorios de 96 bits.

  • PBKDF2: Estira las claves en papel de 132 bits a claves de 256 bits, utilizadas para cifrar «identidades de usuario».

  • AES-256-GCM: Se utiliza para cifrar el contenido de cada publicación. También ofrece autenticación al producir una etiqueta de autenticación de 128 bits, pero este es un aspecto menos importante porque las publicaciones se verifican mediante una firma generada por el autor (véase el paso 1 anterior).

  • RSA-OAEP: Se utiliza para cifrar «claves de tema» e «identidades de usuario» para su almacenamiento seguro en el servidor. Todas las claves RSA-OAEP tienen 4096 bits de longitud.

  • RSA-PSS: Se utiliza para firmar el contenido de cada publicación para verificar su autenticidad. Todas las claves RSA-PSS tienen 4096 bits de longitud.

Primitivas

El sistema utiliza un conjunto de primitivas construidas sobre las proporcionadas por el navegador a través de la API de criptografía web.

  • encrypt y decrypt: Se utilizan para cifrar y descifrar el contenido de las publicaciones. encrypt toma un JSON, una clave AES-256-GCM y una clave pública RSA-PSS y genera una sola cadena codificada en Base64; decrypt toma una cadena codificada en Base64 y una clave AES-256-GCM y genera el objeto JSON inicial;

  • verify: Se utiliza para verificar el contenido de las publicaciones después del descifrado;

  • exportKey y importKey: Se utilizan para exportar e importar «claves de tema»;

  • exportIdentity y importIdentity: Se utilizan para exportar e importar «identidades de usuario».

Tipos de claves:

  • claves de tema (AES-256-GCM)

    • se utilizan para cifrar cada publicación en un tema (las publicaciones se cifran individualmente)
    • se generan por tema, en el lado del cliente por el autor original utilizando la primitiva API WebCrypto generateKey
    • se cifran con la clave pública del usuario para cada usuario que tiene acceso al tema específico utilizando la primitiva API WebCrypto wrapKey
    • se almacenan (cifradas) en el lado del servidor para cada usuario en PluginStore
  • par de claves RSA (claves pública y privada) (RSA-OAEP y RSA-PSS, 4096 bits)

    • se utilizan para cifrar todas las claves de tema a las que un usuario tiene acceso
    • se generan por usuario en el lado del cliente por el autor original utilizando la primitiva API WebCrypto generateKey y se comparten entre todos los dispositivos del usuario
    • lado del servidor: la identidad pública se almacena tal como fue exportada por el cliente, pero la identidad privada siempre estará cifrada con la clave de contraseña
    • lado del cliente: las claves pública y privada se almacenan como CryptoKey en IndexedDb; si no es posible, utilizará window.localStorage (en Safari)
  • claves de contraseña (derivadas utilizando PKBDF2 con 128.000 iteraciones)

    • se utilizan para cifrar «identidades de usuario» para su almacenamiento seguro en el servidor
    • derivadas de una clave en papel (o la contraseña del usuario por razones de compatibilidad)

Modelos de amenazas

Instancia de Discourse comprometida

Un atacante que pueda inyectar código podría, en teoría, acceder a información cifrada sirviendo código malicioso, que descifra el contenido cifrado y envía las publicaciones en texto plano a otro servidor. Para hacer esto posible, es suficiente tener acceso a una cuenta de administrador y crear un componente de tema con el código malicioso.

Los mecanismos de protección predeterminados, como CSP, pueden detectar y mitigar los ataques de cross-site scripting (XSS) que también podrían representar una forma de inyectar código malicioso.

Ataque de intermediario

En los ataques de intermediario, el atacante intercepta la comunicación entre el usuario y el servidor, lo que le permite leerla o alterarla. Dado que el plugin cifra todo antes de enviarlo, un atacante no puede descifrar nada simplemente escuchando. De manera similar, como la información se autentica, el atacante no puede alterarla.

Sin embargo, el atacante podría servir código malicioso de vuelta al usuario y seguir un ataque similar al presentado en la sección anterior. Esto se mitiga parcialmente mediante HTTPS, lo que reduce considerablemente la probabilidad de ataque.

Notas

El plugin ya tiene una pequeña historia y eso se puede ver al examinar el código fuente y notar las dos implementaciones del protocolo v0 (inicial, versión alfa-beta) y v1. El protocolo v0 ya no se utiliza para cifrar nuevas publicaciones, pero se mantiene para continuar descifrando las antiguas. El nuevo protocolo incluye la autenticidad de los textos cifrados y todas las publicaciones se firman con la clave privada del autor.

Otros recursos

99 Me gusta
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?

11 publicaciones se dividieron en un nuevo tema: Ocultar completamente publicaciones parciales para juego de rol

¿Cómo puedo habilitar el envío de mensajes cifrados a grupos? Todos los usuarios del grupo y el remitente del mensaje tienen el cifrado habilitado, pero todavía recibo el mensaje de error:

“No tienes permiso para enviar mensajes cifrados a grupos.”

3 Me gusta

No creo que actualmente sea posible enviar mensajes privados cifrados a grupos.

2 Me gusta

¿Significa esto que el buzón de grupo se rompe? ¿Y/O invitar a un grupo a un mensaje privado no funcionaría?

Esto, no fue posible en primer lugar.

¿Necesito enviar un informe de error sobre esto que está roto?

Todo parece activo, excepto la demora normal al abrir, pero los MP no están cifrados.

1 me gusta

No es necesario hacer publicaciones duplicadas, pero si prefieres convertirlo en un informe de Contribute > Bug en lugar de una solicitud de #soporte, puedes seguir estas pautas y luego recategorizarlo: Writing an effective bug report

Aunque cabe señalar que tanto los informes de errores como las solicitudes de soporte pueden tardar en recibir atención, especialmente los fines de semana.

5 Me gusta

:mega: Lamentablemente, debido a la tasa de adopción relativamente baja y al alto costo de mantenimiento, el soporte para discourse-encrypt se eliminará después del próximo lanzamiento estable de core en el primer trimestre de 2025.

La publicación original de este tema se ha actualizado con más información, y presentaremos una advertencia automática para los administradores de los sitios afectados.

14 Me gusta

Esperanza de que esto se desarrolle en el futuro.
Esto es muy importante/útil en datos/blockchain/seguridad.

7 Me gusta

10 publicaciones se dividieron en un nuevo tema: No mostrar temas y MP a administradores a menos que sean participantes

Continuando la discusión de Discourse Encrypt (obsoleto):

Ha llegado el momento y la última actualización de Discourse parece ser incompatible con Discourse Encrypt.

Nuestros síntomas son que nadie puede responder a una publicación; el sistema comienza a cargar la vista de respuesta pero nunca logra cargar el editor real.

Desactivar Discourse Encrypt elimina el problema, volver a activarlo lo reintroduce.

Dado que este plugin está obsoleto, no lo informo como un error, solo lo informo para que otros puedan esperar este comportamiento.

Además, si alguien conoce recursos que podamos compartir con personas que deseen descargar mensajes cifrados y decodificarlos sin conexión, se lo agradeceríamos.

5 Me gusta