WhatsApp backup conversation files are now saved with the
.crypt8 extension. This means that WhatsApp has once again changed (do they ever stop??!!) the encryption algorithm used to generate the chat history message backups that are saved on the SD card.
Changes between crypt7 and crypt8
As far as the encryption algorithm is concerned, there are no changes between
crypt8 files. For
crypt8, an additional step has been introduced – gunzip the decrypted output file.
crypt8 update, WhatsApp has also disabled the Android ADB backup feature. This method was used previously to extract the keys on a non-rooted phone. So, what this means, is that the
key file that holds the encryption keys cannot be retrieved anymore unless your phone is rooted. We can confirm that the
android:allowBackup feature has been turned off by running aapt (Android Asset Packing Tool) on the latest WhatsApp APK file.
$ aapt dump xmltree com.whatsapp.apk AndroidManifest.xml | grep allowBackup A: android:allowBackup(0x01010280)=(type 0x12)0x0
Extract Key File
To decrypt the
crypt8 files, you will need the key file. The key file stores two sets of decryption keys – the actual encryption key,K and an initialisation vector called IV . WhatsApp stores the key file in a secure location.
Using a rooted phone, launch ADB shell, switch to root and copy the key file to the SD card.
$ adb shell android$ su android# cp /data/data/com.whatsapp/files/key /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/key
Extract crypt8 Backup File
Pull the encrypted WhatsApp messages file from your phone using ADB.
$ adb pull /sdcard/WhatsApp/Databases/msgstore.db.crypt8
Extract Decryption Keys
The encryption method being used is AES with a key length of 256 bits and an initialisation vector size of 128 bits. The 256-bit AES key is saved from offset 0x7E till 0x9D in the file. Offsets start from 0x00. Extract the AES key with hexdump and assign the value to variable
$k. You can choose either one of the two commands below. Both will give the same result.
$ k=$(hexdump -ve '2/1 "%02x"' key | cut -b 253-316)
$ k=$(dd if=key bs=1 skip=126 count=32 2>/dev/null | hexdump -ve '2/1 "%02x"')
$k variable will hold a 64-digit hexadecimal value in ASCII that is actually 256 bits in length.
Next, extract the IV or the initialisation vector and assign the value to variable
$iv. For WhatsApp version before
v2.12.38, the IV value is saved from offset 0x6E till 0x7D in the key file. Again, you can choose either one of the two commands below. Both will give the same result.
$ iv=$(hexdump -ve '2/1 "%02x"' key | cut -b 221-252)
$ iv=$(dd if=key bs=1 skip=110 count=16 2>/dev/null | hexdump -ve '2/1 "%02x"')
For WhatsApp version from
v2.12.38 onwards, the IV value is saved from offset 0x33 till 0x42 in the crypt8 file and not in the
key file. Use one of the following commands to extract IV.
$ iv=$(hexdump -n 67 -ve '2/1 "%02x"' msgstore.db.crypt8 | cut -b 103-134)
$ iv=$(dd if=msgstore.db.crypt8 bs=1 skip=51 count=16 2>/dev/null | hexdump -ve '2/1 "%02x"')
$iv variable will hold a 32-digit hexadecimal value in ASCII that is actually 128 bits in length.
Strip Header in crypt8 File
Before we start the decryption process, we will need to strip the 67 byte header from the
$ dd if=msgstore.db.crypt8 of=msgstore.db.crypt8.nohdr ibs=67 skip=1
The above command will strip the the first 67 bytes from the
crypt8 file and save it to a file with extension
crypt8.nohdr. If you look at the contents of the header, the IV value is actually stored there – between offset 0x33 till 0x42.
The file size of the header stripped file must be divisible by 128 bits or 16 bytes. For example, the size of my output file is
16216176 bytes – a number that is divisible by 16. If the file size is not in multiples of 16 bytes, then most probably your file is corrupted.
$ ls -l msgstore.db.crypt8.nohdr -rw-r--r--+ 1 ibrahim users 16216176 Dec 17 18:35 msgstore.db.crypt8.nohdr
Decrypt crypt8 File
Now we have the necessary parameters to decrypt the
crypt8.nohdr file using the
$ openssl enc -aes-256-cbc -d -nosalt -nopad -bufsize 16384 -in msgstore.db.crypt8.nohdr -K $k -iv $iv | gunzip > msgstore.db
$ openssl enc -aes-256-cbc -d -nosalt -bufsize 16384 -in msgstore.db.crypt8.nohdr -K $k -iv $iv | gunzip > msgstore.db
$iv variables hold the AES encryption key and IV values that we retrieved using
hexdump earlier. A non encrypted SQLite database file will be generated and saved to a file called
I got the following warning message from
gunzip utility when using the
openssl command with the
-nopad option. I assume that the warning can be safely ignored.
"gzip: stdin: decompression OK, trailing garbage ignored"
openssl command has been modified to prevent
Updated (18-May-2015): Force
hexdump to print all input data by using
-v option, else
hexdump could print identical data with asterisk instead.
Related: Extract WhatsApp Password on Android