SQLCipher с исключением библиотеки сохранения состояния комнаты в SQLCipherUtils.getDatabaseState

У меня есть база данных Room в моем приложении для Android, а в моем AppClass у меня есть логика, которая проверяет состояние шифрования базы данных, чтобы обрабатывать некоторые потенциальные операции шифрования, которые могут потребоваться в базе данных. Однако всякий раз, когда я вызываю SQLCipherUtils.getDatabaseState в зашифрованной базе данных, он генерирует исключение SQLiteException. Но самое забавное, что состояние, которое возвращается из getDatabaseState, не равно нулю и работает отлично, а блок try-catch, окружающий вызов getDatabaseState, не улавливает исключение. Таким образом, насколько я могу судить, исключение не влияет на остальную логику. Однако неприятно видеть, что эта ошибка появляется в LogCat каждый раз, когда приложение запускается после того, как база данных была зашифрована. Итак, мой вопрос: действительно ли эта ошибка указывает на проблему? Если да, то как я могу это исправить, а если нет, как отключить ошибку?

Логика базы данных в классе приложения (исключение выбрано в первой строке):

    try {
        // Get database state
        SQLCipherUtils.State state = SQLCipherUtils.getDatabaseState(getApplicationContext(), DB_NAME);

        // Check whether database is encrypted
        if (state == SQLCipherUtils.State.UNENCRYPTED) {
            // If it's unencrypted, encrypt the database
            try {
                // Get database instance
                FinancesDatabase db = FinancesDatabase.getDatabase(getApplicationContext());

                // Close database
                db.close();

                // Encrypt database with encryption key
                SQLCipherUtils.encrypt(getApplicationContext(), DB_NAME, sharedPrefs.getEncryptKey());
                Timber.i("Successfully encrypted database!");

            } catch (IOException e) {
                Timber.e(e, "Failed to encrypt previously unencrypted database!");
            }
        } else if (state == SQLCipherUtils.State.ENCRYPTED)
            // Otherwise, good to go
            Timber.i("Database is encrypted.  No action necessary.");

        else if (state == SQLCipherUtils.State.DOES_NOT_EXIST)
            // No database found.  Normal if first launch
            Timber.w("No database found.");

    } catch(Exception e) {
        Timber.e(e, "Failed to get database encryption state!");
    }

Исключение:

E/Database: file is not a database: , while compiling: select count(*) from sqlite_master;
net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master;
    at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
    at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
    at net.sqlcipher.database.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
    at net.sqlcipher.database.SQLiteProgram.<init>(SQLiteProgram.java:89)
    at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:48)
    at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:60)
    at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1867)
    at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1785)
    at net.sqlcipher.database.SQLiteDatabase.keyDatabase(SQLiteDatabase.java:2486)
    at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2415)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1149)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1116)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1065)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1019)
    at com.commonsware.cwac.saferoom.SQLCipherUtils.getDatabaseState(SQLCipherUtils.java:62)
    at com.commonsware.cwac.saferoom.SQLCipherUtils.getDatabaseState(SQLCipherUtils.java:46)
    at edu.usm.cs.csc414.pocketfinances.AppClass.onCreate(AppClass.java:118)
    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1125)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6056)
    at android.app.ActivityThread.-wrap1(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1764)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6938)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

Реализация SQLCipherUtils.getDatabaseState в библиотеке:

public static State getDatabaseState(Context ctxt, String dbName) {
    SQLiteDatabase.loadLibs(ctxt);

    return(getDatabaseState(ctxt.getDatabasePath(dbName)));
}



public static State getDatabaseState(File dbPath) {
    if (dbPath.exists()) {
      SQLiteDatabase db=null;

      try {
        db=
          SQLiteDatabase.openDatabase(dbPath.getAbsolutePath(), "",
            null, SQLiteDatabase.OPEN_READONLY);

        db.getVersion();

        return(State.UNENCRYPTED);
      }
      catch (Exception e) {
        return(State.ENCRYPTED);
      }
      finally {
        if (db != null) {
          db.close();
        }
      }
    }

    return(State.DOES_NOT_EXIST);
}
3
0
2 444
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это записывается напрямую от SQLCipher для Android. Он будет регистрироваться каждый раз, когда будет использована неверная парольная фраза. getDatabaseState() пытается открыть базу данных с пустой строкой в ​​качестве ключевой фразы, поскольку это «кодовая фраза» для незашифрованной базы данных.

Ваши варианты, чтобы избежать этого сообщения журнала:

  • Не используйте SQLCipher для Android или

  • Не используйте getDatabaseState(), а также убедитесь, что пользователь никогда не укажет неверную парольную фразу.

Извините, сэр, я не понимаю вашей точки зрения. Мне нужно использовать getDatabaseState() для проверки данных, выходящая из базы данных зашифрована или нет? Пожалуйста, помогите мне в этом. Я тоже застрял в той же проблеме. Спасибо

Ravindra Kushwaha 08.01.2021 13:05

@RavindraKushwaha: Если у вас те же симптомы, что и у человека, задавшего исходный вопрос, значит, у вас нет проблемы. Это трассировка стека, регистрируемая SQLCipher для Android. Ваше приложение не дает сбоев. Это ожидаемое и нормальное поведение.

CommonsWare 08.01.2021 14:30

Спасибо, сэр :) Какая проблема, я теперь получаю: - 1). Я шифрую существующую базу данных, и она успешно шифруется .. 2). Когда я повторно запускаю приложение в четное время (каждый второй раз), мое приложение выдает сбой и не создает никаких журналов.

Ravindra Kushwaha 08.01.2021 14:53

Другие вопросы по теме