androidandroid-roomsqlcipher-android

How to migrate a Room database from one encryption passphrase to another?


I ran into an issue where an application I'm working on has encryption enabled for the Room database, using SQLCipher, but the actual passphrase was not formed securely. I have the new, secure method of setting up new databases up and running, but there's a problem: how to migrate the existing database to use the new passphrase?

I have set up a method to check whether or not the database uses the unsecure passphrase, like so:

if (DatabaseEncryptor.isUnsecure()) {
    // Old, unsecure database in use; should migrate to a secure one
}

// All should be good now, set up the secure support factory
builder.openHelperFactory(DatabaseEncryptor.getSupportFactory(context))
    .fallbackToDesctructiveMigration()

Is it possible to just change the passphrase for the existing database? If not, how can the data be transferred from the old, unsecure database to the new, secure database?


Solution

  • Found out that re-keying the database is rather straight-forward. Here's the solution I ended up using:

    val dbFilePath = context.getDatabasePath(DATABASE_NAME)
    if (dbFilePath.exists()) {
        SQLiteDatabase.loadLibs(context)
        val db = SQLiteDatabase.openDatabase(
            dbFilePath.absolutePath,
            OLD_PASSPHRASE,
            null,
            SQLiteDatabase.OPEN_READWRITE
        )
    
        if (db.isOpen) {
            db.rawExecSQL("PRAGMA key = '${OLD_PASSPHRASE}'")
            db.rawExecSQL("PRAGMA rekey = '${NEW_PASSPHRASE}'")
            db.close()
        }
    }