Extract WhatsApp Password on Android

WhatsApp uses a customised version of XMPP (Extensible Messaging and Presence Protocol) as the communication protocol. Upon installation, it creates a user account using one’s phone number (with country code prefix) as the username (Jabber ID: [phone number]@s.whatsapp.net). A password is generated using an unknown algorithm on the server end and sent to the client. Previously the password was derived from the phone’s IMEI or the WiFi MAC address.

On Android, WhatsApp stores both the username and password in 2 separate files kept in the private storage area. The me file stores the username or Jabber ID and the pw file stores the password.

/data/data/com.whatsapp/files/me
/data/data/com.whatsapp/files/pw

The files are stored in a Java serialized object format. The password field is also encrypted (as usual!).

Extract WhatsApp Password File

There are two ways to extract this file. The first method requires a rooted phone. Using ADB shell, switch to root and copy the file to the SD card.

$ adb shell
android$ su
android# cp /data/data/com.whatsapp/files/pw /sdcard
android# exit
android$ exit

Once the file has been copied to the SD card, use ADB again to copy it to your computer.

$ adb pull /sdcard/pw

The second method is to use the ADB backup feature. This is your only option if your phone is not rooted. For more detailed information on performing backups using ADB, read this article – Android ADB Backup, Extract, Restore.

$ adb backup -f com.whatsapp.ab -noapk com.whatsapp

Convert the Android Backup file into a TAR archive.

$ dd if=com.whatsapp.ab ibs=24 skip=1 | openssl zlib -d > com.whatsapp.tar

Next, extract the password file and move it to the current working directory.

$ tar xf com.whatsapp.tar apps/com.whatsapp/f/pw
$ mv apps/com.whatsapp/f/pw .

The password file is 69 bytes in size. I guess it should be the same size for everyone.

Extract Decryption Keys

We will need to extract 3 keys from the password file: salt, IV and the encrypted key. The salt is a 4 byte number found within offset 0x1D and 0x20. Offsets start from 0x00. Extract the salt using dd command.

$ dd if=pw bs=1 skip=29 count=4 > pw_salt

The above will give a 4-byte or 32 bit salt value. For a hex dump of the value, use hexdump.

$ hexdump -e '2/1 "%02x"' pw_salt

The IV or the initialisation vector is a 16-byte or 128-bit value found within offset 0x21 and 0x30. Let’s extract the IV with dd command.

$ dd if=pw bs=1 skip=33 count=16 > pw_iv

Finally, extract the encrypted key. It’s a 20-byte or 160-bit number. Offset is between 0x31 and 0x44 (or end of file).

$ dd if=pw bs=1 skip=49 count=20 > pw_ekey

Now you will have 3 files containing each of the 3 keys: pw_salt, pw_iv and pw_ekey.

Decrypt WhatsApp Password

Decryption is done in 2 steps. First, we need to use the PBKDF2 key derivation function. This function needs a pass phrase that is derived from a known key and the WhatsApp username. First, create the pass phrase file pbkdf2_pass.bin with the known key using xxd – a tool to create a binary file from a hex dump.

$ echo c2991ec29b1d0cc2b8c3b7556458c298c29203c28b45c2973e78c386c395 | xxd -r -p > pbkdf2_pass.bin

Next, append the username or your mobile number to the pass phrase. The number must be in international format but without the + sign. So, if your country code is +65 and if your mobile number is 91234567, the username becomes 6591234567.

$ echo -n 6591234567 | hexdump -e '2/1 "%02x"' | xxd -r -p >> pbkdf2_pass.bin

Now, we have the inputs for the PBKDF2 function. The PBKDF2 function needs a small C program as openssl does not seem to support it from the command line.

Save the C program to a file called wa_pbkdf2.c and compile it using gcc.

$ gcc -o wa_pbkdf2 wa_pbkdf2.c -lssl

If you get any errors like undefined reference to `PKCS5_PBKDF2_HMAC_SHA1', then try linking with the crypto library instead of the ssl library.

$ gcc -o wa_pbkdf2 wa_pbkdf2.c -lcrypto

gcc will create a binary called wa_pbkdf2. Now, proceed to generate the output hash from the PBKDF2 function using the C program.

$ ./wa_pbkdf2 pw_salt 16 < pbkdf2_pass.bin > pbkdf2_key.bin

We are done with step 1 of the decryption process. Step 2 involves AES OFB 128-bit decryption. We need two variables, K and IV. The input message is the encrypted key kept in the pw_ekey file. K can be found from the output of the wa_pbkdf2 program. IV is kept in the pw_iv file. For K and IV we need the values in hex dump format. Extract the values and initialise the variables $k and $iv.

$ k=$(hexdump -e '2/1 "%02x"' pbkdf2_key.bin)
$ iv=$(hexdump -e '2/1 "%02x"' pw_iv)

Now, we can decrypt using openssl.

$ openssl enc -aes-128-ofb -d -nosalt -in pw_ekey -K $k -iv $iv -out wa_password.key

The output will be saved to the file wa_password.key. To view the actual password, encode the output using base64.

$ base64 wa_password.key

The WhatsApp passsword will be printed out.

Updated (22-Dec-2014): Added gcc command to compile with crypto library.

Updated (14-Feb–2015): Extracting password file using ADB Backup feature is no longer applicable.

Related: How to Decrypt WhatsApp crypt7 Database Messages

Related: How to Decrypt WhatsApp crypt8 Database Messages

Related: How to Extract Unencrypted Whatsapp Chat Messages

ibrahim = { interested_in(unix, linux, android, open_source, reverse_engineering); coding(c, shell, perl, php, python, java, javascript, nodejs, angular, react); plays_on(xbox, ps4); linux_desktop_user(true); }