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?

3
  • "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. Commented Apr 23, 2021 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. Commented Apr 23, 2021 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? Commented May 6, 2021 at 5:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.