wa-crypt-tools: decrypting and re-encrypting WhatsApp backups
Manage WhatsApp .crypt12, .crypt14 and .crypt15 files.
At a glance
- What is it?
- wa-crypt-tools is a Python suite that decrypts and encrypts WhatsApp and WhatsApp Business .crypt12, .crypt14 and .crypt15 backup files, given the 64-character key, with five command line tools and a small GUI called wagui. Decryption is solid, encryption is marked beta, and the project is GPL-3.0 licensed.
- Who is it for?
- wa-crypt-tools fits an examiner or a user who holds the backup key and needs the database out of a .crypt file for analysis, and it does not fit anyone who needs to re-create a backup that WhatsApp will accept as its own, because the encryption path is beta and depends on header fields the library does not model.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Everything here needs the key, and the key is shown to you exactly once
This is a toolkit for WhatsApp backups, and the whole design follows from one fact about how WhatsApp encrypts them.
The tools decrypt and encrypt `.crypt12`, `.crypt14` and `.crypt15` files from WhatsApp and WhatsApp Business. To decrypt, you need the key file or the 64-character long key, and you can also hand the tools a screenshot of the key instead. The key file is named `key` when the backup is crypt14, and `encrypted_backup.key` when it is crypt15, the encrypted end-to-end backup format. The tools work out what they were handed, so a screenshot can go wherever the key file would go, with no extra flag.
That last point is not a convenience detail, it is the practical workflow. WhatsApp shows the 64-digit key once and never again, so most people who want to decrypt a backup have a photograph of it rather than a file. The optional dependency for that path is `KeyFactory.new` on an image, and it needs the tesseract binary as well, installed as `tesseract-ocr` on Debian and Ubuntu or through `brew install tesseract` on macOS.
The project's own description points at a broader forensics suite for anyone who needs more than encryption and decryption, whapa, which is a separate project by a different author. What this repository covers is the cryptography layer, and it does it in a way that is deliberately usable without a terminal, because the target audience includes people who are not going to read a command line help message.
Five console tools with different jobs, and one window
The package installs five console entry points and one GUI, and they are split by function rather than by being five versions of the same thing.
`wadecrypt` is the decryptor. Its usage takes the key file, the encrypted file and the output name, and it will not write over a file that already exists unless you pass `-y` or `--yes`. `waencrypt` is the encryptor, and it takes the key file, the decrypted file and the output name, with the same no-overwrite behaviour unless `-y` is given. `wainfo` reports what a backup file is, and `wacreatekey` creates a key file. `waguess` guesses offsets.
The window, `wagui`, is a small graphical interface that covers decrypting: pick your key, pick the backup, press Decrypt. It also identifies a file as soon as you pick it, the way `wainfo` does. Encrypting, creating key files and guessing offsets stay in the command line tools, and the documentation is explicit about that boundary.
A detail in the packaging explains how the Windows build behaves. The GUI is registered as a gui-script rather than a script, which is what makes the Windows executable a console-less `wagui.exe`, so a double-click opens the window and nothing else. The console tools remain console tools on every platform.
There is a standalone build for people who do not want to install Python at all. Every release carries a self-contained build: `wagui-windows-x64.exe` for Windows, `wagui-macos-arm64.zip` for macOS on Apple Silicon, and `wagui-linux-x64` for Linux, which needs `chmod +x` first. The macOS build is not code-signed, so the first launch has to go through a right-click and Open rather than a double-click.
Decrypting a crypt15 backup is a two-line command
The decrypt path is the settled one, and the example in the documentation is short enough to reproduce.
wadecrypt encrypted_backup.key msgstore.db.crypt15 msgstore.dbThe three arguments are the key file, the encrypted file and the name of the output. The run prints a line confirming the key was loaded, `Crypt15 / Raw key loaded`, and then a done message, which is the two-line shape of a successful decrypt.
The underlying file format is the reason the cryptography stack looks the way it does. The dependencies are `pycryptodomex` for the AES work, `protobuf` for the message and header structures, and `javaobj-py3` for reading Java serialised objects, since parts of the backup format are Java serialised and Python's standard library has no reader for them. The `proto/` directory in the repository holds the protobuf definitions, and the packaging is built with setuptools and setuptools-scm.
For the notebook and cloud routes, the project also ships a `notebook.ipynb` version of the program for people who work in Jupyter, and a hosted Google Colab notebook so that nothing has to be installed locally at all. For a forensic workflow that touches a device once, running the tool in a browser tab and never touching the local disk is a meaningful property, and the project thought to offer it.
Encryption is beta, and the reference file is the way to make it work
The encryptor carries a warning in its own output, `This script is in beta stage`, and the documentation does not pretend otherwise. It says encryption is more complex and untested, and advises using another encrypted file from the same account as a reference.
With `--reference`, `waencrypt` reproduces the referenced backup byte for byte. The IV, the header, including fields the library does not model, and the compression level all come off the reference, so re-encrypting an unmodified database gives back the md5 you started with. That is a strong property and the reason to prefer this route.
waencrypt --reference msgstore.db.crypt15 encrypted_backup.key msgstore.db msgstore-new.db.crypt15The compression level is a separate knob, `-c` or `--compression-level`, which is the zlib level, 9 by default, which is what WhatsApp uses now. It compressed at 1 historically, and with `--reference` the level is taken from the reference, so reproducing an older backup needs nothing extra.
Without a reference file, you have to supply the header parameters yourself, and the documentation is candid about which of them cannot be inferred. The feature list, `--enable-features`, is needed for 2019-and-later databases; these are the database migration flags WhatsApp records in the header, and there is no way to infer them from a database file. The defaults are what a 2.26.34.7 msgstore carries, which is all of them. `--max-feature` is 39 at the time of writing, `--wa-version` defaults to 2.26.34.7, `--jid` is the last two numbers of the account's phone number and defaults to 00, and the backup version should be 1.
Only a msgstore carries feature information. Every other backup in the `WhatsApp/Backups/` directory, `wa.db`, `stickers.db` and the rest, carries none, which is what `wainfo` reports as no feature table found. To write a header of that shape, you pass `--enable-features` with nothing after it, an empty list, and `--max-feature` then does nothing.
The .crypt format is a moving target, and the tool shows its age
Two details in the project tell you how much to trust it for a long-running case.
The first is the version trail. The only tagged release is v0.1.0, published on 2024-08-23, while the package metadata in `pyproject.toml` declares version 0.2.0 and setuptools-scm is listed among its build requirements. The last push to the repository was on 2026-10-13, so work is continuing, but there has been no new tag in a long time.
The second is the hard-coded default version string, 2.26.34.7, used for `--wa-version` and as the source of the default feature flags. That is a specific WhatsApp build, and it is the build whose migration flags the project uses when you do not supply a reference. Whether that is still the right default depends on how the current WhatsApp header looks, and the project gives you no way to check other than the `wainfo` output on a backup you have.
The formats themselves are the real fragility. A backup format that evolves with the app will change, and a tool that models the header of a particular era will mis-read a newer one. The `wainfo` tool is the honest first step, since it tells you what it thinks the file is before you commit to decrypting it.
The repository also carries a `CHANGELOG.md`, a `SECURITY.md`, a `CITATION.cff` and a `CODE_OF_CONDUCT.md`, and the test suite is wired to coveralls through the `.coveragerc` file, so the project has the usual hygiene of a maintained Python package even with a single release tag.
Where this tool is the wrong choice
The first case is someone who does not have the key. The tools are explicit that the key or a screenshot of it is required, and there is no path around that, which is exactly what you want from a tool handling this kind of material. If you are looking for a way to read a backup without the key, this is the wrong repository, and the design of the tool makes that answer obvious rather than hiding it.
The second case is producing a backup that WhatsApp itself will accept. The encryption path is in beta, and the reference-file route only reproduces a header byte for byte when it has a real backup from the same account to copy the fields from. Without that, you are reconstructing a header from a hard-coded version string, and a mismatch there produces a file that looks plausible and is not accepted.
The third case is a full mobile forensics examination. This repository is the cryptography layer, and it stops where the backup file ends. Parsing the decrypted database into messages, contacts and media, correlating timelines, and working with the other artefacts on a device are the job of a different tool, and the documentation points at whapa for a more complete suite. Reaching for wa-crypt-tools expecting a full examination workflow will get you a decrypted database and nothing more.
One practical limit is worth naming for the pip route on Linux. The GUI needs tkinter, which is part of Python but packaged separately, `python3-tk` on Debian and Ubuntu or `python3-tkinter` on Fedora, and the project recommends a virtual environment to avoid conflicts with other packages. The downloadable build sidesteps all of it, since it has tkinter built in and needs no Python at all.
Editorial conclusion
wa-crypt-tools fits an examiner or a user who holds the backup key and needs the database out of a .crypt file for analysis, and it does not fit anyone who needs to re-create a backup that WhatsApp will accept as its own, because the encryption path is beta and depends on header fields the library does not model. Before you run it, note that the key file is named `key` for crypt14 backups and `encrypted_backup.key` for crypt15 ones, and that encryption without a reference backup requires you to supply the migration feature flags yourself.
Frequently asked questions
What key does wa-crypt-tools need to decrypt a WhatsApp backup?
You need the key file or the 64-character long key, and a screenshot of the key also works because the tools work out what they were handed. The key file is named `key` for a crypt14 backup and `encrypted_backup.key` for a crypt15 one.
How do I install wa-crypt-tools?
Run `python -m pip install wa-crypt-tools` for the stable version, or `python -m pip install git+https://github.com/ElDavoo/wa-crypt-tools` for the development version. There is also a Google Colab notebook and a Jupyter notebook version, and standalone `wagui` builds for Windows, macOS and Linux that need no Python.
How do I decrypt a crypt15 backup with wadecrypt?
Pass the key file, the encrypted file and the output name, for example `wadecrypt encrypted_backup.key msgstore.db.crypt15 msgstore.db`. The tool will not overwrite an existing file unless you pass `-y` or `--yes`.
Is the encryption side of wa-crypt-tools reliable?
It is marked beta, and the tool prints a beta warning when it runs. The recommended approach is to pass `--reference` with another encrypted file from the same account, which takes the IV, header and compression level from that file so re-encrypting an unmodified database reproduces the original md5.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/eldavoo-wa-crypt-tools)