# Discourse Encrypt (deprecated)

**URL:** https://meta.discourse.org/t/discourse-encrypt-deprecated/107918
**Category:** Plugin
**Tags:** official, encrypt, end-of-life
**Created:** [March 4, 2019, 8:42pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918 "2019-03-04T20:42:32Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [March 4, 2019, 8:42pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/1 "2019-03-04T20:42:32Z")

</div>

> [@](#):
>
> ### ⚠ discourse-encrypt is deprecated, and support will be dropped in Q1 2025.
> 
> We’ve taken this decision based on the very low adoption rate, and high maintenance costs for such a complex feature.
> 
> To aid migration away from the plugin, two new settings have been introduced:
> 
> `allow_new_encrypted_pms` (default true) - disable this to prevent users from creating new encrypted messages
> 
> `allow_decrypting_pms` (default false) - enable this to show a ‘decrypt PM’ button at the top of every encrypted message, and also enable the ‘bulk decyption’ button in a user’s “security” preferences.
> 
> ![individual topic decryption](https://global.discourse-cdn.com/meta/original/4X/0/6/8/0687371fe3c9fb7eac938dbb4284cd50ed8bda1a.jpeg) ![bulk decryption](https://global.discourse-cdn.com/meta/original/4X/4/9/d/49d8ee34afe29e4ad4d5097a263d15f288e40426.png)
> 
> Server administrators can check the number of encrypted messages remaining by running this command on the console:
> 
> ```ruby
> Topic.joins(:encrypted_topics_data).count
> 
> ```
> 
> To print a more detailed list of topic-ids and participants, use this command:
> 
> ```ruby
> Topic.joins(:encrypted_topics_data).each{|topic| puts "#{topic.id}: #{topic.topic_allowed_users.map(&:user).map(&:username).join(', ')}"};
> 
> ```

> **Original Plugin Description**
>
> | | | |
> | --- | --- | --- |
> | :discourse2: | **Summary** | **Discourse Encrypt** enables private, encrypted messaging between end-users. All sensitive information is stored securely on the server and is encrypted and decrypted only on the client-side. |
> | 🛠 | **Repository Link** | [https://github.com/discourse/discourse-encrypt](https://github.com/discourse/discourse-encrypt) |
> | 📖 | **Install Guide** | [How to install plugins in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157) |
> 
> > [@](#):
> >
> > :discourse2: As this is an #official plugin maintained by the Discourse team, #Support, #Contribute > Bug, #Contribute > UX, and #Contribute > Feature requests can be made in the respective categories here on Meta, and tagged with the appropriate plugin tag. Click on a link below to get one started. 👍
> > 
> > [❓&nbsp; **Support**](https://meta.discourse.org/new-topic?category_id=6&body=%3E%20Before%20asking,%20did%20you%20search%20first%3F%20Press%20%F0%9F%94%8D%20at%20the%20upper%20right%20to%20search.&tags=encrypt "Ask for support on configuring and using Discourse Encrypt") [🐛&nbsp; **Bug**](https://meta.discourse.org/new-topic?category_id=1&tags=encrypt "A bug report means something is broken, preventing normal/typical use of the plugin") [👀&nbsp; **UX**](https://meta.discourse.org/new-topic?category_id=9&tags=encrypt "Discussion about the user interface of Discourse Encrypt, and how features are presented (including language and UI elements)") [💡&nbsp; **Feature**](https://meta.discourse.org/new-topic?category_id=2&tags=encrypt "Discussion about how existing Discourse Encrypt features can be improved or enhanced, and how proposed new features could work")
> 
> ## Three easy steps to use this plugin
> 
> 1. Enable encryption and activate current device.
> 
> 1. Send an encrypted message. The recipient must also have enabled encryption.
> 
> Optionally, you can determine the time after which the whole message or specific post will be permanently destroyed
> 
> 1. Read secret messages. Encryption must be activated first to read them.
> 
> Note: In this example, the user was prompted for paper key again because encryption was deactivated (by logging out or explicitly deactivating it from preferences screen).
> 
> ## Technical information
> 
> This plugin gives users the possibility to communicate securely through Discourse, by using an end-to-end encryption scheme. Most of plugin’s logic is implemented on the client-side and the server-side handles only public or encrypted information. It does not encrypt any post metadata, such as names of participants in the conversation, posted time, likes, small actions, etc; uploads are encrypted, but their presence is not because the system must associate uploads with posts to prevent deleting them.
> 
> The whole code is [open-source](https://github.com/discourse/discourse-encrypt) and security enthusiasts are welcome to review it. For any further information, do not hesitate to contact me or the team. 🙂
> 
> > **read more...**
> >
> > ### Summary
> > 
> > The goal of this plugin is to offer integrity and confidentiality of the encrypted contents, and to protect it against information leaks and unauthorized users. The following sections describe the usual operation mode, used algorithms and threat models.
> > 
> > To use this system, users enroll once by generating a “user identity” consisting of two 4096-bits RSA keys, one for encryption and another for signing. Users can export their “identity” for safe keeping or store it on the server, encrypted after generating a paper key. These two methods serve as backups or are used to enroll new devices.
> > 
> > [Paper keys](https://en.wikipedia.org/wiki/Paper_key) (inspired by [RFC 1751](https://tools.ietf.org/html/rfc1751) and [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)) are human-readable keys that are used to securely store the “user identity” on the server. A paper key consists of 12 random words, picked from a list of 2048 words, offering 121-bits of entropy (the first word is used as a label). To encrypt the “user identity” with a paper key, the system will first derive the encryption key using [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) to [stretch](https://en.wikipedia.org/wiki/Key_stretching) the paper key into a 256-bit [AES-GCM](https://en.wikipedia.org/wiki/Galois/Counter_Mode) key.
> > 
> > #### Creating an encrypted post
> > 
> > To create a new post, the user (their browser) will:
> > 
> > 1. sign the current post content using their private signing key;
> > 
> > 2. generate a new “topic key” (a [AES-256-GCM](https://en.wikipedia.org/wiki/Galois/Counter_Mode) key) - which is going to be used to encrypt the post, some post metadata and the title of the new topic (if available);
> > 
> > 3. fetch the public keys of all participants and encrypt the “topic key” for each of them;
> > 
> > 4. send to the server the encrypted post ([Base64](https://en.wikipedia.org/wiki/Base64) encoded) and the encrypted topic keys (also [Base64](https://en.wikipedia.org/wiki/Base64) encoded) of each participant.
> > 
> > ![Encrypt Post](https://global.discourse-cdn.com/meta/original/3X/5/e/5ed7e7273aaeaea31f35a081d42eb6d7275bd398.png)
> > 
> > The pseudocode for the encryption operation would be something like:
> > 
> > ```ruby
> > 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
> > 
> > ```
> > 
> > #### Reading an encrypted post
> > 
> > To read a post, the user (their browser) will:
> > 
> > 1. fetch the encrypted post payload (post plaintext and signature) and encrypted topic key;
> > 
> > 2. use their private encryption key to decrypt the encrypted topic key;
> > 
> > 3. use the decrypted topic key to decrypt the encrypted post payload;
> > 
> > 4. fetch the public signing key of the poster and verify the post signature.
> > 
> > ### Algorithm Suite
> > 
> > This plugin makes extensive use of the cryptographic primitives implemented in [Web Crypto API](https://www.w3.org/TR/WebCryptoAPI/), which are available in any of the modern browsers [Discourse supports](https://github.com/discourse/discourse#requirements) (except Internet Explorer).
> > 
> > - **`getRandomValues` [PRNG](https://en.wikipedia.org/wiki/Pseudorandom_number_generator)**: It generates paper keys and 96-bits random IVs.
> > 
> > - **[PBKDF2](https://en.wikipedia.org/wiki/PBKDF2)**: It stretches the 132-bit paper keys to 256-bit keys, used for encrypting “user identities”.
> > 
> > - **[AES-256-GCM](https://en.wikipedia.org/wiki/Galois/Counter_Mode)**: Used to encrypt each post’s content. It also offers authentication by producing an authentication tag of 128-bits, but this is a less important aspect because posts are verified using a signature generated by the poster (see step 1 above).
> > 
> > - **[RSA-OAEP](https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding)**: Used to encrypt “topic keys” and “user identites” for safe-keeping on the server. All RSA-OAEP keys are 4096-bits long.
> > 
> > - **[RSA-PSS](https://en.wikipedia.org/wiki/Probabilistic_signature_scheme)**: Used to sign each post’s content for verifying authenticity. All RSA-PSS keys are 4096-bits long.
> > 
> > ### Primitives
> > 
> > The system uses a set of primitives built on top of those provided by the browser via [Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/).
> > 
> > - **[encrypt](https://github.com/discourse/discourse-encrypt/blob/5a97a43b59168a284d097793afed1eabc7831cc6/assets/javascripts/lib/protocol.js.es6#L133) and [decrypt](https://github.com/discourse/discourse-encrypt/blob/5a97a43b59168a284d097793afed1eabc7831cc6/assets/javascripts/lib/protocol.js.es6#L169)**: Used to encrypt and decrypt post contents. `encrypt` takes a JSON, an AES-256-GCM key and a RSA-PSS public key and outputs a single Base64 encoded string; `decrypt` takes a Base64 encoded string and an AES-256-GCM key and outputs the initial JSON object;
> > 
> > - **[verify](https://github.com/discourse/discourse-encrypt/blob/5a97a43b59168a284d097793afed1eabc7831cc6/assets/javascripts/lib/protocol.js.es6#L192)**: Used to verify post contents after decryption;
> > 
> > - **[exportKey](https://github.com/discourse/discourse-encrypt/blob/5a97a43b59168a284d097793afed1eabc7831cc6/assets/javascripts/lib/protocol.js.es6#L234) and [importKey](https://github.com/discourse/discourse-encrypt/blob/5a97a43b59168a284d097793afed1eabc7831cc6/assets/javascripts/lib/protocol.js.es6#L254)**: Used to export and import “topic keys”;
> > 
> > - **[exportIdentity](https://github.com/discourse/discourse-encrypt/blob/5a97a43b59168a284d097793afed1eabc7831cc6/assets/javascripts/lib/protocol.js.es6#L64) and [importIdentity](https://github.com/discourse/discourse-encrypt/blob/5a97a43b59168a284d097793afed1eabc7831cc6/assets/javascripts/lib/protocol.js.es6#L93)**: Used to export and import “user identities”.
> > 
> > #### Types of keys:
> > 
> > - **topic keys** ([AES-256-GCM](https://en.wikipedia.org/wiki/Galois/Counter_Mode))
> > 
> > - **RSA key-pair (public and private keys)** ([RSA-OAEP](https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding) and [RSA-PSS](https://en.wikipedia.org/wiki/Probabilistic_signature_scheme), 4096-bits)
> > 
> > - **passphrase keys** (derived using [PKBDF2](https://en.wikipedia.org/wiki/PBKDF2) with 128,000 iterations)
> > 
> > ### Threat models
> > 
> > #### Compromised Discourse Instance
> > 
> > An attacker which can inject code could in theory access encrypted information by serving malicious code, which decrypts the encrypted content and sends the plaintext posts to another server. To make this possible, it is enough to have access to an administrator account and create a theme component with the malicious code.
> > 
> > Default protection mechanisms such as CSP can detect and mitigate [Cross Site Scripting (XSS) attacks](https://en.wikipedia.org/wiki/Cross-site_scripting) that could also represent a way of injecting malicious code.
> > 
> > #### Man-in-the-Middle Attack
> > 
> > In Man-in-the-Middle attacks, the attacker intercepts the communication between the user and server, giving them the ability to read or alter it. Because the plugin encrypts everything before sending, an attacker cannot decrypt anything by simply eavesdropping. Similarly, because information is authenticated the attacker cannot alter it.
> > 
> > However, the attacker could serve malicious code back to the user and follow a similar attack to the one presented in the previous section. This is partially mitigated by HTTPS, which is considerably reducing the attack probability.
> > 
> > ## Notes
> > 
> > The plugin already has a little history and that can be seen while browsing the source code and noticing the two implementations of the protocol `v0` (initial, alpha-beta release) and `v1`. Protocol `v0` is no longer used to encrypt new posts, but kept to continue decrypting old ones. New protocol includes authenticity of the ciphertexts and all posts are signed with the private key of the poster.
> 
> ## Other Resources
> 
> - [Original spec for this plugin on Meta’s Marketplace](https://meta.discourse.org/t/encrypted-personal-messages/98765)

> Last edited by @david 2024-12-03T15:46:08Z
> 
> > **Check document**
> >
> > Perform check on document:

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [April 23, 2024, 9:17am UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/224 "2024-04-23T09:17:04Z")

</div>

11 posts were split to a new topic: [Full hide of partial posts for role-playing game](https://meta.discourse.org/t/full-hide-of-partial-posts-for-role-playing-game/305045)

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [May 8, 2024, 9:08am UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/227 "2024-05-08T09:08:01Z")

</div>

How can I enable sending encrypted messages to groups? All users of the group and the message sender have encryption enabled, but I still get error message:

“You do not have permission to send encrypted messages to groups.”

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [May 8, 2024, 9:41am UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/228 "2024-05-08T09:41:49Z")

</div>

I don’t believe it’s currently possible to send encrypted PMs to groups.

---

<div class="post-metadata">

### Author: ![Heliosurge](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/heliosurge/32/571810_2.png) [@Heliosurge](https://meta.discourse.org/u/Heliosurge)
#### Post date: [May 10, 2024, 5:59am UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/229 "2024-05-10T05:59:56Z")

</div>

Does this mean that group mailbox becomes broken? and/Or inviting a group to pm would not work?

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [May 15, 2024, 3:31pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/230 "2024-05-15T15:31:20Z")

</div>

This, it wasn’t possible in the first place.

---

<div class="post-metadata">

### Author: ![anon48433008](https://avatars.discourse-cdn.com/v4/letter/a/22d042/32.png) [@anon48433008](https://meta.discourse.org/u/anon48433008)
#### Post date: [July 7, 2024, 5:18pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/231 "2024-07-07T17:18:14Z")

</div>

Do I need to submit a bug report on this being broken?

> [@Encrypt plug-in issue](https://meta.discourse.org/t/encrypt-plug-in-issue/315241):
>
> I seem to have an issue with the encryption plug-in seems to be twofold First I noted I could read a PM from my transactional email service So I sent that test message to someone who recently just had to reactivate their encryption, they lost their key, so I feel confident they do have it working It can be read, I didn’t think that was possible As I had set up a second account today to test a different setting I decided to log into that and send my own Here’s the second thing This…

Everything appears active short missing the normal lag in opening but PM’s are not encrypted

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [July 7, 2024, 6:11pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/232 "2024-07-07T18:11:35Z")

</div>

There’s no need to cross-post, but if you’d like to make it a #Contribute > Bug report rather than a #Support request you can follow these guidelines and then recategorise it - [Writing an effective bug report](https://meta.discourse.org/t/writing-an-effective-bug-report/183671)

Though it’s worth noting that both bug reports and support requests can take time to pick up traction, especially at the weekend.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [December 3, 2024, 1:19pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/234 "2024-12-03T13:19:58Z")

</div>

📣 Unfortunately due to the relatively low adoption rate, and high cost of maintenance, support for discourse-encrypt will be dropped after core’s next stable release in Q1 2025.

The [original post of this topic](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918) has been updated with more information, and we’ll be introducing an automatic warning for admins of affected sites.

---

<div class="post-metadata">

### Author: ![cmdntd](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cmdntd/32/192008_2.png) [@cmdntd](https://meta.discourse.org/u/cmdntd)
#### Post date: [December 11, 2024, 6:25am UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/235 "2024-12-11T06:25:14Z")

</div>

Hope for dev this on future.  
This is very important/useful one in data/blockchain/security.

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [December 23, 2024, 3:30pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/236 "2024-12-23T15:30:10Z")

</div>

10 posts were split to a new topic: [Do not show topics and PMs to admins unless they are participants](https://meta.discourse.org/t/do-not-show-topics-and-pms-to-admins-unless-they-are-participants/344065)

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [December 26, 2024, 4:29pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/237 "2024-12-26T16:29:43Z")

</div>



---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [September 22, 2025, 4:30pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/238 "2025-09-22T16:30:09Z")

</div>



---

<div class="post-metadata">

### Author: ![MentalNomad](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mentalnomad/32/95159_2.png) [@MentalNomad](https://meta.discourse.org/u/MentalNomad)
#### Post date: [September 8, 2025, 8:45pm UTC](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918/239 "2025-09-08T20:45:20Z")

</div>

Continuing the discussion from [Discourse Encrypt (deprecated)](https://meta.discourse.org/t/discourse-encrypt-deprecated/107918):

The time has come and the latest Discourse update appears to be incompatible with Discourse Encrypt.

Our symptoms are that nobody is able to reply to a post; the system starts to load the reply view but never manages to load up the actual editor.

Toggling off the Discourse Encrypt eliminates the problem, toggling it back on brings the problem back.

As this plugin is deprecated, I’m not reporting it as a bug, I’m just reporting it so that others can expect this behavior.

Also, if anyone knows of resources that we could point to for individuals who would like to be able to download encrypted messages and decode them offline, that would be appreciated.
