First encrypted Room database unlock is up to ~4x slower after upgrading Room 2.5.2 → 2.8.4 and sqlcipher-android 4.11.0 → 4.17.0

オープン
#91 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
説明が足りない
活発さ
静か
技術スタック
android, kotlin

調査の方向性

Start with the SQLiteDatabaseHook.postKey() instrumentation and reproduce the first SELECT COUNT(*) FROM sqlite_schema query across the listed Room and sqlcipher-android versions. Compare the controlled measurements and inspect the first-unlock path for changes affecting lazy KDF, first-page decryption, or key verification. Done means isolating the regression or documenting a safe diagnostic that distinguishes the Room and SQLCipher effects.

索引モデルが issue の本文から書いたものです。

説明

First encrypted Room database unlock is up to ~4x slower after upgrading Room 2.5.2 → 2.8.4 and sqlcipher-android 4.11.0 → 4.17.0

Summary

After upgrading Room from 2.5.2 to 2.8.4 and net.zetetic:sqlcipher-android from 4.11.0 to 4.17.0, opening existing encrypted Room databases became up to approximately four times slower during application startup.

The slowdown is concentrated in the first SQL statement executed after SQLiteDatabaseHook.postKey(). Queries issued after the connection is fully open do not show the same regression.

Environment

  • Platform: Android
  • Database integration: Room with a SQLCipher-backed SupportSQLiteOpenHelper.Factory
  • Database type: existing SQLCipher-encrypted Room databases
  • Journal mode: WAL
  • Password, database files, device and build configuration: unchanged between measurements
  • Device /RMX6688

Dependency change

Configuration Room sqlcipher-android Observed first-unlock cost
Before 2.5.2 4.14.0 Baseline
After 2.8.4 4.17.0 Up to approximately 4x slower

Additional controlled measurements

We also held Room at 2.8.4 and compared sqlcipher-android 4.11.0 with 4.17.0 on the same test setup. This independently shows a substantial regression on the SQLCipher version axis:

Room sqlcipher-android Samples Mean Median P90 Min–max
2.8.4 4.11.0 80 529.46 ms 494.30 ms 809.51 ms 197.19–1,011.59 ms
2.8.4 4.17.0 137 1,588.07 ms 1,314.43 ms 2,919.85 ms 654.63–3,519.30 ms

The 4.17.0 result is:

  • 3.00x higher by mean;
  • 2.66x higher by median;
  • 3.61x higher at P90.

Representative log entries:

# Room 2.8.4 + sqlcipher-android 4.17.0
SQLCipher key derivation and verification cost: 2775.801539ms
SQLCipher key derivation and verification cost: 3244.882154ms
SQLCipher key derivation and verification cost: 3519.295308ms

# Room 2.8.4 + sqlcipher-android 4.11.0
SQLCipher key derivation and verification cost: 346.516385ms
SQLCipher key derivation and verification cost: 478.817230ms
SQLCipher key derivation and verification cost: 562.362538ms

Instrumentation

The measurements were collected with the following SQLiteDatabaseHook:

internal class SqlCipherDebugLogHook private constructor(
    private val delegate: SQLiteDatabaseHook?,
) : SQLiteDatabaseHook {

    override fun preKey(connection: SQLiteConnection) {
        delegate?.preKey(connection)
    }

    override fun postKey(connection: SQLiteConnection) {
        delegate?.postKey(connection)
        val startNs = System.nanoTime()
        runCatching {
            connection.executeForLong(
                "SELECT COUNT(*) FROM sqlite_schema;",
                null,
                null,
            )
        }.onSuccess {
            val elapsedMs = (System.nanoTime() - startNs) / 1_000_000.0
            logd(TAG, "SQLCipher key derivation and verification cost: ${elapsedMs}ms")
        }
    }
}

SQLCipher performs key derivation lazily. Therefore, the measured interval is not the duration of the postKey() callback itself and should not be interpreted as isolated PBKDF time. It measures the first schema query after postKey(), which forces lazy KDF, first-page decryption, and key verification. The trivial COUNT(*) query overhead is also included.

Steps to reproduce

  1. Create an encrypted Room database, then close it or kill the application process.
  2. Configure Room with a SQLCipher-backed SupportSQLiteOpenHelper.Factory and WAL.
  3. Install a SQLiteDatabaseHook that runs and times SELECT COUNT(*) FROM sqlite_schema; in postKey().
  4. Open the existing database during application startup.
  5. Record the first-query duration logged by the hook.
  6. Repeat across fresh process starts using the same device, database, passphrase, and build configuration.
  7. Compare the old and new dependency combinations.

Expected behavior

First unlock/open performance should remain close to the earlier version when the database, passphrase, cipher settings, device, and build configuration are unchanged.

Actual behavior

The first SQL statement that forces key derivation and verification is substantially slower on sqlcipher-android 4.17.0. The original joint Room/SQLCipher upgrade showed an increase of up to approximately 4x; the controlled Room 2.8.4 measurements show a 3.00x mean and 3.61x P90 increase from SQLCipher 4.11.0 to 4.17.0.

Isolation matrix

The following matrix would separate the Room and SQLCipher effects for the exact versions in the original report:

Room sqlcipher-android Status
2.8.4 4.11.0 Measured: mean 529.46 ms, P90 809.51 ms
2.8.4 4.17.0 Measured: mean 1,588.07 ms, P90 2,919.85 ms

Questions

  1. Were there changes between sqlcipher-android 4.11.0 and 4.17.0 that could increase lazy KDF, first-page decryption, or key verification time for an existing database?
  2. Did any default cipher, KDF, compatibility, or native build settings change across these versions?
  3. Could 4.17.0 derive or verify the key more than once when Room opens multiple WAL connections?
  4. Is timing the first trivial schema query from postKey() a valid way to compare SQLCipher first-unlock cost across versions?
  5. Which safe diagnostics or PRAGMA values would help isolate the increase without exposing the database key?
主要言語
Java
スター
277
フォーク
38
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

sqlcipher/sqlcipher-android のほかの issue

sqlcipher/sqlcipher-android の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。