Extracting Messages from Signal Desktop

Posted on | 395 words | ~2 mins

While Signal might be the best crypto messenger out there, it is terrible when it comes to simple convenience functions. Sometimes I want to export a chat to archive it or share it with someone who has lost parts of an important conversation due to a key change. But Signal doesn’t offer any official way to create a CSV or even a PDF export.

On the other hand, Signal is Open Source , and it’s not very hard to find a way to roll your own export.

I’m using Signal Desktop, but it should be possible to find a similar way for Android or iOS versions of Signal.

Start by making a copy of the Signal database. Signal uses sqlite, so all data is neatly stored in a single file. Depending on your OS, you can find the database at:

  • Linux: ~/.config/Signal/sql/db.sqlite
  • Mac: ~/Library/Application Support/Signal/sql/db.sqlite
  • Windows: C:\Users\<YourName>\AppData\Roaming\Signal\sql\db.sqlite

You can decrypt the database using sqlcipher and then extract all data using sqlite . Still, it’s a lot more comfortable to use SQlite Browser (Open Source), which can handle sqlcipher encrypted databases.

If you’re using a Mac, you can install SQlite Browser using Homebrew by running:

brew install --cask db-browser-for-sqlite

Start SQlite Browser and open your copy of the DB. You’ll be prompted to enter a passphrase. Change the value of the dropdown from ‘Passphrase’ to ‘Raw Key’.

You’ll find the key in the config.json file in your Signal config directory. The config directory is the same as above without the /sql/db.sqlite part.

Enter 0x into the textbox and then append the key found in the config.json file (without quotes) and click ‘OK’.

The key actually just lies there in plain text, so keep in mind that anyone who can obtain a copy of your DB might also be able to obtain a copy of the key to decrypt it.

If you want to export a specific conversation, first look at the table conversations and copy the id of the conversation you want to export. You can filter the messages table by this conversation id in the conversationId column. Export the filtered table as CSV.

The most relevant columns are sent_at (UNIX timestamp of message in milliseconds), type (incoming or outgoing), and of course body (the message content).

You can use LibreOffice/Excel/Numbers to shape the CSV to a format of your liking and export it as PDF.