cadence’s website.

Some changes will be applied after reloading.
Some changes will be applied after reloading.

Advanced: How to manually decrypt a Matrix JSON event using Element

This is not a security issue or a hack.

This guide assumes you have Element desktop logged in and you're able to decrypt the messages in your client. If Element refuses to decrypt then this guide isn't for you, sorry.

This guide is for people who have a bunch of JSON of an encrypted event, perhaps obtained from their homeserver, and they want to legitimately decrypt it using their own client's keys.

Also, if you want to decrypt the history of an entire room to save as plaintext, you can do this using the built-in "export chat" button. Save as plain text and turn up the size limit to 100 MB. For massive rooms (>100k events) this could take a couple of hours. Element may appear to be frozen during the process but it will finish eventually.

How to do it

Press Ctrl-Shift-I to open the console, then paste the following code, replacing the middle line with your event JSON.

(e => mxMatrixClientPeg.matrixClient.crypto.decryptEvent.bind(mxMatrixClientPeg.matrixClient.crypto)(new ([0].timeline[0].constructor)(e)).then(c => console.log(c.clearEvent)))(

How it works

  • mxMatrixClientPeg.matrixClient.crypto.decryptEvent.bind(mxMatrixClientPeg.matrixClient.crypto)
    Prepares the built-in decryptEvent function so that it can be called.
    Gets a copy of the MatrixEvent type. This is done by looking up an existing event, and getting its constructor.
  • new (...)(e)
    Constructs a new MatrixEvent on the provided JSON.
  • .then(c => console.log(c.clearEvent))
    Once it's done decrypting, displays the result.
  • (e => ...)({})
    An anonymous function to make it easier to see where to paste the event JSON.

Hope this helps!


A seal on a cushion spinning a globe on its nose.
Another seal. They are friends!