# Upgrading from android-database-sqlcipher to sqlcipher-android

**URL:** https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741
**Category:** SQLCipher
**Created:** [September 5, 2024, 1:20pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741 "2024-09-05T13:20:19Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 5, 2024, 1:20pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/1 "2024-09-05T13:20:19Z")

</div>

Is " **Option 2: Backwards Compatibility**" would work nowadays for migrating from net.zetetic:android-database-sqlcipher:3.5.7 to net.zetetic:android-database-sqlcipher:4.5.4?

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 5, 2024, 1:42pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/2 "2024-09-05T13:42:18Z")

</div>

Hi @FrozenPyrozen,

Yes, you could use the compatibility PRAGMA to upgrade your library to 4.5.4 and access a SQLCipher 3.x database.

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 5, 2024, 1:49pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/3 "2024-09-05T13:49:27Z")

</div>

I’m not a native android dev so I wanted to check should I use it like this?

```auto
// DatabaseHelper.java
 @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        // Apply PRAGMAs to maintain SQLCipher 3 compatibility
        db.execSQL("PRAGMA cipher_compatibility = 3;");
        db.execSQL("PRAGMA cipher_page_size = 1024;");
        db.execSQL("PRAGMA kdf_iter = 64000;");
        db.execSQL("PRAGMA cipher_hmac_algorithm = HMAC_SHA1;");
        db.execSQL("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;");
    }

```

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 5, 2024, 2:13pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/4 "2024-09-05T14:13:24Z")

</div>

Hi @FrozenPyrozen,

No, if you are using the `android-database-sqlcipher` library, you will want to use the `SQLiteDatabaseHook` and set your compatibility via the `postKey` event:

```auto
SQLiteDatabase hook = new SQLiteDatabaseHook() {
  @Override
  public void preKey(SQLiteDatabase database) {}
  @Override
  public void postKey(SQLiteDatabase database) {
    database.execSQL("PRAGMA cipher_compatibility = 3;");
  }
};

```

You can then provide the `hook` parameter as an argument when opening the database connection. This will guarantee that the compatibility setting is in place before key derivation or any other SQL operation occurs.

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 6, 2024, 9:49am UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/5 "2024-09-06T09:49:36Z")

</div>

Thanks, how to understand where to place a hook?

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 6, 2024, 12:39pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/6 "2024-09-06T12:39:26Z")

</div>

Hi @FrozenPyrozen,

The hook can be provided to the static `openDatabase`/`openOrCreateDatabase` methods found on the `SQLiteDatabase` class, or if you’re using a subclass to the `SQLiteOpenHelper`.

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 9, 2024, 12:41pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/7 "2024-09-09T12:41:46Z")

</div>

I was looking into [MigrateDatabaseFrom3xFormatToCurrentFormatTest](https://github.com/sqlcipher/sqlcipher-android/blob/master/sqlcipher/src/androidTest/java/net/zetetic/database/sqlcipher_cts/MigrateDatabaseFrom1xFormatToCurrentFormatTest.java#L25) as an example, and I’ve seen some issues with `SQLiteConnection` on my Android studio so I’ve created a helper method

```auto
public static SQLiteDatabaseHook migrateDbFromSupportHook() {
        return new SQLiteDatabaseHook() {
            @Override
            public void preKey(SQLiteDatabase database) {}

            @Override
            public void postKey(SQLiteDatabase database) {
                // Apply PRAGMAs to maintain SQLCipher 3 compatibility for net.zetetic:android-database-sqlcipher after 4x version
                database.execSQL("PRAGMA cipher_compatibility = 3;");
                database.execSQL("PRAGMA cipher_page_size = 1024;");
                database.execSQL("PRAGMA kdf_iter = 64000;");
                database.execSQL("PRAGMA cipher_hmac_algorithm = HMAC_SHA1;");
                database.execSQL("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;");
            }
        };

    }

```

and passing this hook into every `openDatabase` method calling in project. Is this okay?

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 9, 2024, 7:42pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/8 "2024-09-09T19:42:48Z")

</div>

Hi @FrozenPyrozen,

Once you set the compatibility version you don’t need to set the other pragma items as they are set on your behalf. See the [implementation](https://github.com/sqlcipher/sqlcipher/blob/master/src/sqlcipher.c#L2462-L2473) for reference.

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 10, 2024, 11:10am UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/9 "2024-09-10T11:10:22Z")

</div>

I’ve got dew questions:

1. Everything above, but only with ` database.execSQL("PRAGMA cipher_compatibility = 3;");` would be enough?
2. I’ve got `import net.sqlcipher.database.SQLiteException;` and error “Cannot resolve symbol ‘SQLiteException’”. Does `SQLiteException` moved somewhere in newer versions?

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 10, 2024, 12:12pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/10 "2024-09-10T12:12:58Z")

</div>

> [@FrozenPyrozen](#):
>
> Everything above, but only with ` database.execSQL("PRAGMA cipher_compatibility = 3;");` would be enough?

Correct.

> [@FrozenPyrozen](#):
>
> I’ve got `import net.sqlcipher.database.SQLiteException;` and error “Cannot resolve symbol ‘SQLiteException’”. Does `SQLiteException` moved somewhere in newer versions?

In the SQLCipher for Android 4.5.4 release \[1\], Android Database SQLite Exception classes are now used for compatibility with Android Support and Room.

* * *

1. [SQLCipher 4.5.4 Release | Zetetic](https://www.zetetic.net/blog/2023/04/27/sqlcipher-4.5.4-release/)

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 10, 2024, 1:12pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/11 "2024-09-10T13:12:46Z")

</div>

Where I could find an info what need to be changed there?

`error: cannot access SupportSQLiteDatabase SQLiteDatabase.loadLibs(context);`

SQLiteDatabase imported from `import net.sqlcipher.database.SQLiteDatabase;`

This error is not visible on Android studio, only on CI/CD when creating build

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 10, 2024, 1:51pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/12 "2024-09-10T13:51:01Z")

</div>

Hi @FrozenPyrozen,

That sounds like a project configuration issue, or possibly your environment. `SupportSQLiteDatabase` is not part of SQLCipher for Android \[1\].

* * *

1. [SupportSQLiteDatabase &nbsp;|&nbsp; Android Developers](https://developer.android.com/reference/androidx/sqlite/db/SupportSQLiteDatabase)

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 19, 2024, 8:01am UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/13 "2024-09-19T08:01:48Z")

</div>

It’s expected after updating app from `net.zetetic:android-database-sqlcipher:3.5.7` to app with `net.zetetic:android-database-sqlcipher:4.5.4` we started to see that app making a logout and need user to login again? This behaviour could be, because of migration?

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 19, 2024, 1:12pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/14 "2024-09-19T13:12:57Z")

</div>

Hi @FrozenPyrozen,

> [@FrozenPyrozen](#):
>
> It’s expected after updating app from `net.zetetic:android-database-sqlcipher:3.5.7` to app with `net.zetetic:android-database-sqlcipher:4.5.4` we started to see that app making a logout and need user to login again? This behaviour could be, because of migration?

That sounds like an application-specific issue, SQLCipher for Android would not directly cause your application to logout.

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 20, 2024, 11:19am UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/15 "2024-09-20T11:19:53Z")

</div>

Got it, just to understand got few questions:

1. If we storing user in `SQLiteDatabase` which imported from `import net.sqlcipher.database.SQLiteDatabase;` and we updating the `sqlcipher` to `4.5.4` and installing newer build, by default do `sqlcipher` library do some changes for example how db was encrypted/decrypted and old data becomes unavailable or it should work by default with prev version created, encrypted db without any changes/logouts?
2. What are the possible triggers/events that could lead to clearing user data from db etc?
3. I currently added:

```auto
    public static SQLiteDatabaseHook migrateDbFrom3xFormatToCurrentSupportHook() {
        return new SQLiteDatabaseHook() {
            @Override
            public void preKey(SQLiteDatabase database) {}

            @Override
            public void postKey(SQLiteDatabase database) {
                // Apply PRAGMA to maintain SQLCipher 3 compatibility for net.zetetic:android-database-sqlcipher after 4x version
                database.execSQL("PRAGMA cipher_compatibility = 3;");
            }
        };

    }

```

and passing this to each function which opens db connection, but also I’ve seen override of `public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)` from `SQLiteOpenHelper`, maybe smth could be added there to support smooth migration from old to new version with backwards compatibility?

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 20, 2024, 1:36pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/16 "2024-09-20T13:36:21Z")

</div>

Hi @FrozenPyrozen,

> [@FrozenPyrozen](#):
>
> we storing user in `SQLiteDatabase` which imported from `import net.sqlcipher.database.SQLiteDatabase;` and we updating the `sqlcipher` to `4.5.4` and installing newer build, by default do `sqlcipher` library do some changes for example how db was encrypted/decrypted and old data becomes unavailable or it should work by default with prev version created, encrypted db without any changes/logouts?

You previously mentioned using SQLCipher for Android 3.5.7. If you are upgrading to SQLCipher for Android 4.5.4, you will need to review the [upgrade recommendations](https://discuss.zetetic.net/t/upgrading-to-sqlcipher-4/3283) as SQLCipher 4 will not open a SQLCipher 3 database by default, there are several approaches to address this.

> [@FrozenPyrozen](#):
>
> What are the possible triggers/events that could lead to clearing user data from db etc?

SQLCipher for Android uses the `DatabaseErrorHandler` (similar to [android.database.sqlite.DatabaseErrorHandler](https://developer.android.com/reference/android/database/DatabaseErrorHandler)) using the [default implementation](https://github.com/sqlcipher/android-database-sqlcipher/blob/master/android-database-sqlcipher/src/main/java/net/sqlcipher/DefaultDatabaseErrorHandler.java#L35) which will delete the file on corruption. This is consistent with the `android.database.sqlite` package. You can override this behavior by providing your own implementation for a `DatabaseErrorHandler` via constructor argument to a `SQLiteOpenHelper` subclass, or the static `openDatabase` or `openOrCreateDatabase` on the `SQLiteDatabase` class.

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [September 23, 2024, 9:16am UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/17 "2024-09-23T09:16:09Z")

</div>

> [@developernotes](#):
>
> You previously mentioned using SQLCipher for Android 3.5.7. If you are upgrading to SQLCipher for Android 4.5.4, you will need to review the [upgrade recommendations](https://discuss.zetetic.net/t/upgrading-to-sqlcipher-4/3283) as SQLCipher 4 will not open a SQLCipher 3 database by default, there are several approaches to address this.

I’ve added `PRAGMA cipher_compatibility = 3;` to `SQLiteDatabaseHook` and passed it to `openDatabase`  
As I remember we discussed that it’s enough, I think that without it SQLCipher 3 database wouldn’t be opened.

In my case we store user login data in db and could update app from `net.zetetic:android-database-sqlcipher:3.5.7` to app with `net.zetetic:android-database-sqlcipher:4.5.4` impact on this data that we need to login again or login should be the same as we would close and open app?

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [September 24, 2024, 1:59pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/18 "2024-09-24T13:59:55Z")

</div>

Hi @FrozenPyrozen,

Since you are using the compatibility setting, you are not updating the database file format. Your application should continue to work when moving the library from 3.5.7 to 4.5.4.

---

<div class="post-metadata">

### Author: ![FrozenPyrozen](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/frozenpyrozen/32/2296_2.png) [@FrozenPyrozen](https://discuss.zetetic.net/u/FrozenPyrozen)
#### Post date: [November 6, 2024, 12:10pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/19 "2024-11-06T12:10:14Z")

</div>

Hi @developernotes, I’ve used a migration hook in all places where I’ve got `SQLiteDatabase.openDatabase` do you now other methods where I could place this hook also? Because we have a pin screen and it look like it trying to connect to new db with old approach, In some cases I’ve get an error with message `net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master ` looks like that I need to add migration hook somewhere else also

My case:

1. I’ve open app with 3.5.7, do login (save data in db 3.5.7)
2. I’m hiding app to background and install 4.5.4
3. When open app again I’ve got error `net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master `  
If I would kill app instead hiding on step 2, I would be logged out, so maybe there other places where I need to place migration hook to have backwards compatibility for supporting 3.5.7 db version

---

<div class="post-metadata">

### Author: ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)
#### Post date: [November 6, 2024, 1:21pm UTC](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741/20 "2024-11-06T13:21:03Z")

</div>

Hi @FrozenPyrozen,

You should only be linking your application with one version of SQLCipher. It sounds like you may need to evaluate your application source further to determine all call sites that interface with SQLCipher for Android. You can apply the hook to both the static methods available on the `SQLiteDatabase` class for opening/creating a database, along with any derivatives associated with the `SQLiteOpenHelper`.

[Next page](https://discuss.zetetic.net/t/upgrading-from-android-database-sqlcipher-to-sqlcipher-android/6741.md?page=2)
