ElDavoo / wa-crypt-tools

Manage WhatsApp .crypt12, .crypt14 and .crypt15 files.
GNU General Public License v3.0
583 stars 78 forks source link

Decrypt WhatsApp Encrypted Google Backup - crypt15 - with custom password #13

Closed vHanda closed 2 years ago

vHanda commented 2 years ago

Hi. I've enabled end-to-end whatsapp backups on my Android phone with a custom password. These are being stored in my Google Drive. I've downloaded all the files via this awesome tool. It has given me a msgstore.db.crypt15 file.

I'm confused on how to decrypt this, as I don't have a 'backup key', just a password. I tried just writing the password in the encrypted_backup.key file, but I get the following error - [F] The keyfile is not a valid Java object: Invalid file magic: 0x3732

Any help would be appreciated.

ElDavoo commented 2 years ago

Hi, This is not the way it works. I suggest you to read WhatsApp 's backup encryption white paper. I will summarize the paper for you.

Basically the decryption key is stored on WhatsApp servers. You send the password to their servers (the password is encrypted in such a way that they do not know the password, they only know that you know it) and they give you the key.

In other words: the only purpose of the password is to get the actual key from WhatsApp servers. It is not used in any way for the decryption.

To the best of my knowledge there are no third party programs that download the key for you, and the only way to get the key is to configure WhatsApp on a new phone and get the "encrypted_backup.key" file. The app downloads the key from the server and then stores it locally to decrypt and encrypt new backups.

Let me know if you have further questions.

vHanda commented 2 years ago

Thank you for the clarification.

When enabling the e2e encrypted backups, WhatsApp gives me an option to choose a password or a 64 bit encryption key. From what I understand from here, by choosing the 64-bit key option, I'm not using the "HSM-based Backup Key Vault".

image

The key is given to be like this -

xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx

where x is a hexadecimal number. This gives a "32 byte" key.

I managed to modify the existing code a little bit and make it work -

diff --git a/decrypt14_15.py b/decrypt14_15.py
index 8c79b14..9350420 100644
--- a/decrypt14_15.py
+++ b/decrypt14_15.py
@@ -144,7 +144,12 @@ class Key:
         except OSError as e:
             log.f("Couldn't read keyfile: {}".format(e))
         except (ValueError, RuntimeError) as e:
-            log.f("The keyfile is not a valid Java object: {}".format(e))
+            with open('./encrypted_backup.key', 'r') as file:
+                data = file.read().replace('\n', '').replace(' ', '')
+                if len(data) == 64:
+                    keyfile = bytes.fromhex(data)
+                else:
+                    log.f("The keyfile is not a valid Java object: {}".format(e))

         # We guess the key type from its length
         if len(keyfile) == 131:

Could you please let me know what would be the best way to contribute this? I could add another command line argument?

ElDavoo commented 2 years ago

By choosing the 64-bit key option, I'm not using the "HSM-based Backup Key Vault".

Exactly: how would you prove to the key vault you are the owner of that key? You need another proof of ownership (that is the password).

Could you please let me know what would be the best way to contribute this? I could add another command line argument?

I think that adding an argument would be nice but it might be hard to implement as of now, the program is designed to have a key file as an input.

I will also make an utility to create an encrypted_backup.key from a hex string. Imho this is the easiest way

ElDavoo commented 2 years ago

I added an utility to create an encrypted_backup.key file starting from a hex encoded key.

vHanda commented 2 years ago

I added an utility to create an encrypted_backup.key file starting from a hex encoded key.

Thank you. I really appreciate you taking the time.

I'm going to close this issue as there doesn't seem anything else to do.

ElDavoo commented 2 years ago

I'm going to close this issue as there doesn't seem anything else to do.

There is! :) You can now specify a raw hex string instead of a key file and it will work. I just hope this didn't break anything as I didn't test much.

vHanda commented 2 years ago

There is! :) You can now specify a raw hex string instead of a key file and it will work. I just hope this didn't break anything as I didn't test much.

I tried it out. It works perfectly!