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?
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()
}
}