解决sqlcipher从3.5.9升级到4.0.1引起的崩溃问题

由于客户对移动端的数据库有加密需求,并且最近要优化性能,所以升级了net.zetetic:android-database-sqlcipher库,但是却造成程序崩溃,异常如下:

Caused by: 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:1954)

        at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1840)

        at net.sqlcipher.database.SQLiteDatabase.keyDatabase(SQLiteDatabase.java:2571)

        at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2502)

        at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1204)

        at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1258)

        at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1253)

        at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1238)

        at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1274)

        at org.penguin.project.sqlcipher.MainActivity.InitializeSQLCipher(MainActivity.java:34)

        at org.penguin.project.sqlcipher.MainActivity.onCreate(MainActivity.java:18)

        at android.app.Activity.performCreate(Activity.java:7436)

        at android.app.Activity.performCreate(Activity.java:7426)

        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)

        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3279)

        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3484) 

        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 

        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 

        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 

        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2123) 

        at android.os.Handler.dispatchMessage(Handler.java:109) 

        at android.os.Looper.loop(Looper.java:207) 

        at android.app.ActivityThread.main(ActivityThread.java:7470) 

        at java.lang.reflect.Method.invoke(Native Method) 

        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 

        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958) 

经过研究发现,可以通过以下代码解决崩溃问题:

SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databasePath, ZeteticApplication.DATABASE_PASSWORD, null, new SQLiteDatabaseHook() {

@Override

    public void preKey(SQLiteDatabase database) {

}

@Override

    public void postKey(SQLiteDatabase database) {

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”);

    }

});

至于涉及到到greendao如何解决,明天再研究下,如果需要弄清楚参数的作用,请参考下面的网址:

https://www.zetetic.net/sqlcipher/sqlcipher-api/#key

另外提醒下,PRAGMA部分的语句必须放在postKey方法中执行,否则也会崩溃。

    原文作者:自然V简单
    原文地址: https://www.jianshu.com/p/9579f9cef85b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞