Migration from 2.x format to 3.x failed


#1

WeChat for Android uses SQLCipher to encrypt its data, however the file format is incompatible with SQLCipher 3.x. When i tried to migrate the database file format in my Android app using SQLCipher for Android 3.3.1, things do not work out for me.

Here is my code:

SQLiteDatabase.loadLibs(context);

SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
    public void preKey(SQLiteDatabase database) {
    }

    public void postKey(SQLiteDatabase database) {
        database.rawExecSQL("PRAGMA cipher_use_hmac = off;");
        database.rawExecSQL("PRAGMA cipher_page_size = 1024;");
        database.rawExecSQL("PRAGMA kdf_iter = 4000;");

        Cursor cursor = database.rawQuery("PRAGMA cipher_migrate", new String[]{});
        if (cursor != null) {
            cursor.moveToFirst();
            Log.d(TAG, "cipher_migrate return code: " + cursor.getString(0));
            cursor.close();
        } else {
            Log.d(TAG, "cipher_migrate return cursor is null");
        }
    }
};

SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(dbFile, "password", null, hook);
database.close();

When i executed PRAGMA cipher_migrate in the postKey method of SQLiteDatabaseHook, i got a return code of 1.
The full logcat messages can be found here http://pastebin.com/sbszqP63

Thanks,
Clyde


#2

Note i used other pragma statements according to http://articles.forensicfocus.com/2014/10/01/decrypt-wechat-enmicromsgdb-database/, however i got no luck with these statements removed too.


#3

Are you able to open the database using the command line pragma statements referenced in the article?

If not, then it is likely that the key is incorrect. It is of course possible that WeChat has made some changes to their key generation algorithm in the year since their approach was reverse engineered and published.


#4

Thanks @sjlombardo. It turns out to be a problem of incorrect permissions on the external storage files. Sorry for the nonsense.

And for those who may be of interest, using PRAGMA cipher_migrate in postKey will just work with SQLCipher for Android 3.3.1. However i moved from the latest version 3.x to version 2.2.0, and replacing this pragma with the following is required to make it work.

PRAGMA cipher_use_hmac = off
PRAGMA cipher_page_size = 1024
PRAGMA kdf_iter = 4000

#5

Hello @clydeza

Just to clarify for others:

Those settings are specific to the SQLCipher 1.x database format, not 2.2.0. In 2.x we introduced a per page HMAC, and in 3.x we increased the KDF to 64,000.