Upgrading plain content provider data(backed by SQLite) to encrypted using SQLCipher - Android


#1

I am trying to encrypt data stored in my content provider (backed with SQLite) with App upgrade. I followed below link for this,
enter link description here

While this works perfectly fine if a new installation is done, If I go for an upgrade, app crashes with below error

net.sqlcipher.database.SQLiteException: file is encrypted or is not a database

at android.app.ActivityThread.handleReceiver(ActivityThread.java:3009)
at android.app.ActivityThread.access$1800(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1526)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
Caused by: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database

I even tried to delete the existing tables and create a new table just to see if this solved the problem but no that was of no help either. Please suggest how to fix this, My Helper class is as below,

public class MyDBHelper extends SQLiteOpenHelper {
public MyDBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
SQLiteDatabase.loadLibs(context);
}
public static final String DATABASE_NAME = “mydb.db”;

            private static final int DATABASE_VERSION = 2; // before attempting encryption it was 1

            @Override
            public void onCreate(SQLiteDatabase db) {
                createTables(db);
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                db.execSQL("DROP TABLE IF EXISTS " + "TEST_TABLE");
                createTables(db);
            }

            private void createTables(SQLiteDatabase db){
                db.execSQL(MyDBQueries.CREATE_TEST_TABLE);
            }
        }

My updated provider simply uses a key now to open the db as below,
SQLiteDatabase db = databaseHelper.getWritableDatabase(“encryptionKey”);

Please help me resolve this, If possible without losing any existing content provider data. If not then at least it should allow upgrade from plain data to encrypted.


#2

This question was originally posted on Stack Overflow:

I have posted an answer there. In a nutshell, you have to manually encrypt the database; it will not be automatically encrypted by SQLiteOpenHelper.

(though that would be an interesting feature: if SQLiteOpenHelper cannot open the database for upgrade with the encryption key, try the empty key, and if that works, do the encryption, then perform the upgrade)