0

I am using DBFlow with SQLCipher. I am trying to encrypt the already existing SQLite Database(using DBFlow) with SQLCipher in Android.

I used the following code to encrypt the DB:

private void encryptDB() {
        SQLiteDatabase.loadLibs(this);
        String password = "test123";
        String LEGACY_DATABASE_NAME = "legacy.db";
        String NEW_DATABASE_NAME = "new_crypt.db";
        File newDBFile = getDatabasePath(NEW_DATABASE_NAME);
        File legacyFile = getDatabasePath(LEGACY_DATABASE_NAME);
        if (!newDBFile.exists() && legacyFile.exists()) {
            SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(legacyFile, "", null);
            db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';", newDBFile.getAbsolutePath(), password));
            db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
            db.rawExecSQL("DETACH DATABASE encrypted;");
            db.close();
            db = SQLiteDatabase.openDatabase(newDBFile.getAbsolutePath(), password, null, SQLiteDatabase.OPEN_READWRITE);
            db.close();
            legacyFile.delete();
            newDBFile.renameTo(legacyFile);
        }
    }

The DB is encrypted fine but when I am trying to write any operations:

Place place = new Place();
place.setName("Test");
place.save();

DB Model:

@Table(database = DatabaseManager.class)
public class Place extends BaseModel {
  @Column
  String name;
  // set and get methods goes here
}

then getting the following exception:

io.reactivex.exceptions.UndeliverableException: android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 1032 SQLITE_READONLY_DBMOVED[1032])

I found a similar post here but not found any solution to it.

Also, I found this to encrypt the DBFlow database with SQLCipher and implemented it. Then it is working if I install it as a fresh app but when I install this app on top of the old app which is having not encrypted DB then it is failing.

net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master;

Please suggest how can I fix this?

Shailendra Madda
  • 20,649
  • 15
  • 100
  • 138
  • "when I am trying to write any operations" -- your question does not show any write operations, other than the original encryption itself. I have not used DBFlow, but, given the error message, it feels like you left some sort of DBFlow object around that remembers the pre-encrypted database. Also note that you are leaking a database connection in `encryptDB()`, as you call `openDatabase()` without closing it. Plus, you have an open database connection from that `openDatabase()` call when you go to rename the file. Please close **all** database connections to the database before encrypting it. – CommonsWare Apr 23 '21 at 11:06
  • Write operations are after encrypting the DB. Even I tried with closing the DB as well like `db.close()` but same error. – Shailendra Madda Apr 23 '21 at 11:10
  • @CommonsWare I have updated my question, how I am doing write operation on Place table using DB Flow. Can you suggest what to do here? – Shailendra Madda May 06 '21 at 05:33

0 Answers0