Opening Signal Android Backups with signal-backup-decode

Created by Steven Baltakatei Sandoval on 2021-01-02T04:06Z under a CC BY-SA 4.0 license and last updated on 2021-01-03T02:04Z.


Today I want to document how I extracted messages and attachments from a Signal backup from my Android phone using my Debian machine. The end result is a directory containing:

  • attachments (images, other files attached to Signal messages)
  • avatars (profile images of contacts)
  • stickers
  • an SQLite 3.x database containing timestamped messages and contact information

A Hail Mary script summarizing all the commands is:

mkdir /tmp/tempWorkDir && pushd /tmp/tempWorkDir
sudo apt install -y git rustc libsqlite3-dev libssl-dev pkg-config protobuf-compiler sqlitebrowser
git clone ./localRepo
pushd ./localRepo
cargo install --features "rebuild-protobuf" --locked --path .
~/.cargo/bin/signal-backup-decode signal-2021-01-01-23-59-59.backup --output-path ./output/ --password-file /tmp/sigkey.txt --output-type RAW --force
sqlitebrowser ./output/signal_backup.db &

where ./tmp/sigkey.txt contains the 30-digit backup password (a.k.a. "passphrase") with no spaces or newlines.

Table of Contents

  1. Opening Signal Android Backups with signal-backup-decode
    1. Summary
    2. Background
    3. Procedure
      1. Review Installation Instructions
      2. Install Dependencies
      3. Clone the git repository
      4. Compile signal-backup-decode
      5. Decrypt the Signal backup
      6. Inspect the Signal backup
    4. Conclusion
    5. Software Versions
      1. cargo
      2. git
      3. libsqlite3-dev
      4. libssl-dev
      5. pkg-config
      6. protobuf-compiler
      7. rustc
      8. sqlitebrowser


I use the Signal messaging app for Android for end-to-end encrypted communications. But sometimes I want to be able to archive certain sets of these communications into my own storage system. The Signal app itself doesn't go out of its way to provide such a method. However, since 2018, it doesn't seem to have gone out of its way to make its backup file format a moving target. Therefore, some open source software projects have been available for years that are capable of converting these backup files into useful decrypted forms without many updates. A package I used in 2018 was Pajowu's signal-backup-decode program. Using some notes I took years ago I have updated my personal procedure for decrypting Signal Android backup files; I decided to share these notes since I haven't seen much elsewhere describing how to compile or use this software.

I have tested these instructions on a Debian) 10 machine (specifically PureOS) and a Debian Testing (a 10/11 hybrid; a.k.a. "bullseye)/sid") machine. Although not tested, I imagine the git repository should be compilable on macOS using a different package manager (e.g. Homebrew) to install the dependencies.

These instructions aren't necessary to the desktop versions of Signal since the attachments are not encrypted. Messages must be extracted using a different procedure. As stated in the Signal subreddit, I don't think there is a simple method to extract messages from the iOS version of Signal.


Review Installation Instructions

I used the following sources for instructions on how to form the commands I need:

  • Pajowu's signal-backup-decode github repository. The and Issue pages for this repo are the most useful.
  • A page describing cargo's --locked compile option
  • A Reddit FAQ that mentions signal-backup-decode among other software.

Install Dependencies

On my Debian Testing machine (approximately Debian 11), I installed some dependencies using apt. I selected these according to this Issue page on the git repo.

$ sudo apt install git rustc libsqlite3-dev libssl-dev pkg-config protobuf-compiler

Clone the git repository

The following command can be used to clone the git repository to a working directory where the cargo install command can later be run to start the compiling process.

$ git clone ./localRepo

Compile signal-backup-decode

The git repository contains source code written in the Rust language that can be compiled by running the cargo install command upon the repository's working directory ./localRepo. cargo installs itself as a dependency for rustc. The commands to move into the repository's working directory and executing cargo install upon it are as follows:

$ pushd ./localRepo
$ cargo install --features "rebuild-protobuf" --locked --path .

The --features and --locked options require some more explanation.

The git repository contains a Cargo.lock file which may be used in tandem with the --locked flag in order to force cargo to compile signal-backup-decode using specific versions of dependencies (apparently called "crates") which cargo automatically downloads (explanation here).

The git repository also indicates, according to this issue, that it may be necessary to rebuild a protobuf feature that should already be included in the repository; I kept the --features "rebuild-protobuf" option that apparently asks for the rebuild; it might not be necessary.

Decrypt the Signal backup

The actual backup can be decrypted and extracted to an automatically-generated directory at ./output/ with the following command:

~/.cargo/bin/signal-backup-decode signal-2021-01-01-23-59-59.backup --output-path ./output/ --password-file /tmp/sigkey.txt --output-type RAW --force
04:35:40 [INFO] Output path: ./output-force/
04:35:40 [INFO] Input file: signal-2021-01-01-23-59-59.backup
04:35:40 [INFO] Database Version: 85
             Bytes read: [00:00:25] [##################################################] 3.94GB/3.94GB
Read vs. written frames: [00:00:25] [##################################################] 31144/31144

The end result is the creation of the ./output directory filled with the following items:


Note, the --force option is required since there seems to be a file overwrite problem (see this issue) with a file in preference/. Unless --force is used, the signal_backup.db SQLite 3.x database file is never written.

Inspect the Signal backup

The signal_backup.db file can be opened using sqlitebrowser:

$ sudo apt install sqlitebrowser
$ sqlitebrowser ./output/signal_backup.db

Under the "Browse Data" tab, messages are stored within the sms table.


The process for decrypting backups produced by the Android version of the Signal app hasn't changed much since 2018. The process is complex since it involves compiling an executable binary from the rust language as well as some familiarity with the git version control system. The commands described in this document may need to be altered over time if Signal alters their backup format and the maintainer of signal-backup-decode updates their program's options in response.

Software Versions

Versions of software mentioned in this document are as follows:


$ apt list --installed | grep cargo
cargo/testing,now 0.47.0-3+b1 amd64 [installed,automatic]

$ cargo --version
cargo 1.46.0


$ apt list --installed | grep git
git/testing,now 1:2.29.2-1 amd64 [installed]

$ git --version
git version 2.29.2


$ apt list --installed | grep libsqlite3-dev
libsqlite3-dev/testing,now 3.34.0-1 amd64 [installed]


$ apt list --installed | grep libssl-dev
libssl-dev/testing,now 1.1.1i-1 amd64 [installed]


$ apt list --installed | grep pkg-config
pkg-config/testing,now 0.29.2-1 amd64 [installed]


$ apt list --installed | grep protobuf-compiler
protobuf-compiler/testing,now 3.12.3-2+b2 amd64 [installed]


$ apt list --installed | grep rustc
rustc/testing,now 1.48.0+dfsg1-2 amd64 [installed]

$ rustc --version
rustc 1.48.0


$ apt list --installed | grep sqlitebrowser
sqlitebrowser/testing,now 3.12.1-2 amd64 [installed]

$ sqlitebrowser --version
DB Browser for SQLite Version 3.12.1

Built for x86_64-little_endian-lp64, running on x86_64
Qt Version 5.15.1
SQLite Version 3.33.0.