# Runtime update of Room database password

**URL:** <https://discuss.zetetic.net/t/runtime-update-of-room-database-password/6309>\
**Category:** SQLCipher\
**Created:** [March 5, 2024, 3:34pm UTC](https://discuss.zetetic.net/t/runtime-update-of-room-database-password/6309 "2024-03-05T15:34:04Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Torima](https://avatars.discourse-cdn.com/v4/letter/t/e0b2c6/32.png) [@Torima](https://discuss.zetetic.net/u/Torima)\
**Post date:** [March 5, 2024, 3:34pm UTC](https://discuss.zetetic.net/t/runtime-update-of-room-database-password/6309/1 "2024-03-05T15:34:04Z")

</div>

Since Room does not provide official support for encryption I decided to ask here.

I am trying to update database password of already encrypted database. I manage to do it with suggested `PRAGMA rekey="newKey"`, meaning when I pull the database files from the device and use SQLCipher for Windows, I can read it with `newKey`. Problem happens when I inject the Room database in my repository, that instance probably tries to read the database with old password and I get the `file is not a database` exception.  
It seems to me like underlying SQLite database is encrypted with new key, but Room is not aware of it and uses `oldKey` which was set through `SupportOpenHelperFactory`. So my current pseudo code which works is this:

```auto
fun buildDB(): RoomDB {
  //set builder with old pass
  val builder = Room.databaseBuilder(...).openHelperFactory(SupportOpenHelperFactory("oldKey".toByteArray())).
  var db = builder.build()
  // change db pass
  db.openHelper.writableDatabase.query("PRAGMA rekey = 'newKey';")
  
  // here I still have open connection with newKey so I could do any kind of queries and it works
  // for example 
  // db.openHelper.writableDatabase.query("SELECT COUNT(*) FROM sqlite_schema;")
  
  // close the connection
  db.close()
  // create new builder with new pass
  val builder2 = Room.databaseBuilder(...).openHelperFactory(SupportOpenHelperFactory("newKey".toByteArray())).
  db = builder2.build()

  return db
}

```

then this `db` instance is returned to my `@Provides` and `@Singleton` annotated method in my Dagger module.  
So my questions are

- Why does it work in the `buildDB` function but once that instance is injected into my repository for example, I can not query it? It is same instance but it seems like Room closed the connection and tried to open it with old password.
- Is there a better way to achieve this, without the need to recreate RoomDatabase instance? Is there a way to update the password on already created instance?
- Why is there no `changePassword` function in `SupportSQLiteDatabase` like it was in `SQLiteDatabase`?
