Transfer WhatsApp Messages from Android to iOS

After nearly a decade, I decided to switch back to iPhone for the first time since the iPhone 4. I was willing to spend an afternoon redownloading all my apps and meticulously signing in to each one, but my years of chat history on WhatsApp eluded me. Currently, there is no official way to transfer your chat history from Android to iOS. This may be changing soon, as WhatsApp recently added support for iOS to Samsung transfers on select devices with the promise of support to come soon. Unfortunately, this support did not come soon enough for me and I needed to find another way.

I used two open-source tools to perform the transfer: WhatsApp-Key-DB-Extractor to extract my existing chat database from my Android phone, and watoi to merge and replace my chat history with my iOS database. Note that I have used the kittywhiskers fork of watoi, as it has support for the newer WhatsApp schema. This process does have some limitations outlined in the watoi README.md that include replacing media files and shared locations with placeholders and skipping messages from contacts that have changed IDs (phone numbers).

As always, follow this guide at your own risk and always make a backup. Ensure you read and understand the risks of any code or scripts you run on your devices.

Decrypt the Android database

The WhatsApp Android app encrypts the chat database with a key that is generated during the initial setup. The database and key are both stored in internal storage which is inaccessible unless you have a rooted device or the app has enabled android:allowBackup. While WhatsApp has disabled this option, there are older versions of the app with it still enabled. WhatsApp-Key-DB-Extractor takes advantage of this by sideloading an older version of the app onto your phone and then performs a backup with adb backup.

To begin, enable developer options and USB debugging on your phone. Then install the Android SDK Platform Tools on your computer, and ensure you can see your device.

$ adb devices
b0c554a3	device

Now we can clone the project.

git clone https://github.com/KnugiHK/WhatsApp-Key-DB-Extractor.git
cd WhatsApp-Key-DB-Extractor

Next, I highly recommend you download an older version of the app from a source you trust as it will be installed on your phone and given access to your WhatsApp data. This step is optional, because if you do not provide an APK the script will download one provided by WhatCrypt. Use this at your own risk.

mkdir -p tmp
cp /PATH_TO/YOUR_TRUSTED.APK tmp/LegacyWhatsApp.apk

Finally, unlock your phone and run the script.

bash WhatsAppKeyDBExtract.sh

During this process, your phone will ask you to set a backup password. Make sure to provide the same password to the script when it asks for it. For the sake of simplicity, I left the password blank. When finished, your decrypted database will be in extracted/msgstore.db. Remember this path for later.

Merge and restore to iOS

Compared to Android, the message database on iOS is easily accessible through local backups. Since the database schemas differ, we will be using watoi to handle the merge of our Android messages into the iOS database, and then performing a restore on the device to load them back in.

Before we begin, ensure you have installed and activated WhatsApp on your iOS device, and have sent a couple of messages to contacts (not group chats) to ensure there is something to back up. Then perform a local unencrypted backup to your computer.

We also need to download the WhatsApp IPA from a trusted source that matches the version you have installed on your iOS device, and then unzip it. Remember this path for later.

unzip WhatsApp_Messenger.ipa -d app

Now that we have the prerequisites, the first step is to download and install Xcode, and then build the watoi project.

git clone https://github.com/kittywhiskers/watoi
cd watoi
xcodebuild -project watoi.xcodeproj -target watoi

Use the provided script to find the ID of your backup and export it to an environment variable for later. The backups will be listed with their timestamps, so make sure to pick the latest.

$ scripts/bedit.sh list-backups
total 0
drwxr-xr-x  264 olanmatt  staff  8448 24 Sep 15:30 A3D693F8-C11E7DAEAB3AD639
$ export BACKUP_ID="A3D693F8-C11E7DAEAB3AD639"
Your backup ID will be different from mine. I used the random string A3D693F8-C11E7DAEAB3AD639 as an example here.

Now run the following lines as described in the README.md to extract your database, back up important files, and copy the database to the watoi directory.

export ORIGINALS="originals/$(date +%s)"
mkdir -p $ORIGINALS
scripts/bedit.sh extract-chats $BACKUP_ID $ORIGINALS/ChatStorage.sqlite
scripts/bedit.sh extract-blob $BACKUP_ID Manifest.db $ORIGINALS/Manifest.db
cp $ORIGINALS/ChatStorage.sqlite ./ChatStorage.sqlite

Now we can run the migration code and replace the existing chat database in our backup with the merged one.

build/Release/watio \
    /PATH_TO/WhatsApp-Key-DB-Extractor/extracted/msgstore.db \
    ./ChatStorage.sqlite \
    /PATH_TO/app/Payload/WhatsApp.app/Frameworks/Core.framework/WhatsAppChat.momd
scripts/bedit.sh replace-chats $BACKUP_ID ./ChatStorage.sqlite
Substitute the paths for your msgstore.db and the extracted .ipa directory from earlier.

Finally, restore your device from your latest backup. Once the restore process is complete, your chat history will be completely migrated to iOS. I found this process archived all my chats, so I simply restored them.

Troubleshooting

When trying to compile the Xcode project I encountered the following error:

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

This can be resolved by switching your default version of Xcode to use for command-line tools and then trying to build again.

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

I also encountered an Operation not permitted issue addressed in the watoi README.me regarding terminal permissions. This can be resolved by enabling full disk assess for your terminal app.