sqlcipher - 更改数据库密码失败

时间:2013-10-21 15:57:23

标签: android sqlite sqlcipher

对于这个应用程序,我有一个使用sqlcipher的数据库,该数据库受密码保护。

我有一项活动允许我使用以下代码更改密码:

SQLiteDatabase database = SQLiteDatabase.openDatabase(getDatabasePath("db").getPath() , oldPass, null,0) ;
database.rawExecSQL("PRAGMA rekey = '"+newPass+"';");
database.close();

在执行上一段代码后,应用程序恢复正常操作,同时尝试再次访问数据库,我得到:

10-21 16:40:28.961  26635-26635/com.example            E/Database: CREATE TABLE android_metadata failed
10-21 16:40:28.981  26635-26635/com.example            E/Database: Failed to setLocale() when constructing, closing the database
        net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
        at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
        at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2101)
        at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1967)
        at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:900)
        at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:943)
        at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:107)

其次是:

Caused by: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
    at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
    at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2101)
    at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1967)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:900)
    at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:943)
    at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:107)

任何人都对这里发生的事情有任何暗示或想法?我可能正在更改密码错误或其他内容。

我真的很感激任何帮助。

编辑1:修改传递的执行日志并尝试再次打开DB文件:

10-21 23:22:46.915  17043-17043/com.example            D/testapp: Finalizing DB Facade Object
10-21 23:22:46.945  17043-17043/com.example            D/testapp: saveDBPasswordSettings - oldPass: ##
10-21 23:22:46.945  17043-17043/com.example            D/testapp: saveDBPasswordSettings - newPass: #newpass#
10-21 23:22:46.945  17043-17043/com.example            D/testapp: saveDBPasswordSettings - 0
10-21 23:22:47.025    1462-1788/?                              E/ENSWrapper: return OMX_ErrorNotImplemented - GetExtensionIndex OMX.ST.AFM.pcmprocessing.transducer_equalizer h=0x003a8180  cParameterName=STE.ADM IndexType=unknown OMX_INDEXTYPE [ 0x00000002 ]
10-21 23:22:47.095  17043-17043/com.example            D/testapp: saveDBPasswordSettings - 1
10-21 23:22:47.105  17043-17043/com.example            D/testapp: saveDBPasswordSettings - 2
10-21 23:22:47.105  17043-17043/com.example            D/testapp: saveDBPasswordSettings - 3
10-21 23:22:47.115  17043-17043/com.example            D/testapp: saveDBPasswordSettings - 4
10-21 23:22:47.115  17043-17043/com.example            D/testapp: saveDBPasswordSettings - 5
10-21 23:22:47.125  17043-17043/com.example            D/testapp: saveDBPasswordSettings - 6
10-21 23:22:47.145  17043-17043/com.example            D/testapp: setCacheDbPassword - Called with : newpass
10-21 23:22:47.205  17043-17043/com.example            D/testapp: setDbencriptionAskonstart - Called with : false
10-21 23:22:47.225  17043-17043/com.example            D/testapp: Finalizing DB Facade Object
10-21 23:22:47.235  17043-17043/com.example            D/dalvikvm: Trying to load lib /data/data/com.example/lib/libstlport_shared.so 0x4110ff20
10-21 23:22:47.235  17043-17043/com.example            D/dalvikvm: Shared lib '/data/data/com.example/lib/libstlport_shared.so' already loaded in same CL 0x4110ff20
10-21 23:22:47.235  17043-17043/com.example            D/dalvikvm: Trying to load lib /data/data/com.example/lib/libsqlcipher_android.so 0x4110ff20
10-21 23:22:47.235  17043-17043/com.example            D/dalvikvm: Shared lib '/data/data/com.example/lib/libsqlcipher_android.so' already loaded in same CL 0x4110ff20
10-21 23:22:47.235  17043-17043/com.example            D/dalvikvm: Trying to load lib /data/data/com.example/lib/libdatabase_sqlcipher.so 0x4110ff20
10-21 23:22:47.235  17043-17043/com.example            D/dalvikvm: Shared lib '/data/data/com.example/lib/libdatabase_sqlcipher.so' already loaded in same CL 0x4110ff20
10-21 23:22:47.235  17043-17043/com.example            D/testapp: USING PASSWORD :   newpass
10-21 23:22:47.325    1462-1788/?                              D/ADM: devset:588    STATUS API LEAVE: Opened new device 'Speaker', handle = 101
10-21 23:22:47.405  17043-17043/com.example            I/Database: sqlite returned: error code = 26, msg = file is encrypted or is not a database
10-21 23:22:47.405  17043-17043/com.example            E/Database: CREATE TABLE android_metadata failed
10-21 23:22:47.515  17043-17043/com.example            E/Database: Failed to setLocale() when constructing, closing the database
        net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
        at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
        at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2101)
        at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1967)
        at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:900)
        at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:943)
        at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:107)
        at com.example.db.TestDataSource.open(TestDataSource.java:45)
        at com.example.db.DBFacade.init(DBFacade.java:91)
        at com.example.ui.config.DBPasswordActivity.saveDBPasswordSettings(DBPasswordActivity.java:118)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at android.view.View$1.onClick(View.java:3098)
        at android.view.View.performClick(View.java:3574)
        at android.view.View$PerformClick.run(View.java:14293)
        at android.os.Handler.handleCallback(Handler.java:605)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4448)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
        at dalvik.system.NativeStart.main(Native Method)
10-21 23:22:47.525  17043-17043/com.example            D/AndroidRuntime: Shutting down VM
10-21 23:22:47.525  17043-17043/com.example            W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x40aac210)
10-21 23:22:47.626  17043-17043/com.example            E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.IllegalStateException: Could not execute method of the activity
        at android.view.View$1.onClick(View.java:3103)
        at android.view.View.performClick(View.java:3574)
        at android.view.View$PerformClick.run(View.java:14293)
        at android.os.Handler.handleCallback(Handler.java:605)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4448)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at android.view.View$1.onClick(View.java:3098)
        ... 11 more
        Caused by: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
        at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
        at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2101)
        at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1967)
        at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:900)
        at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:943)
        at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:107)
        at com.example.db.TestDataSource.open(TestDataSource.java:45)
        at com.example.db.DBFacade.init(DBFacade.java:91)
        at com.example.ui.config.DBPasswordActivity.saveDBPasswordSettings(DBPasswordActivity.java:118)
        ... 14 more
10-21 23:22:47.656    1439-1720/?                              D/SurfaceFlinger: screenshot: sw=120, sh=180, minZ=0, maxZ=21035
10-21 23:22:47.656    1862-1299/?                              W/ActivityManager: Force finishing activity com.example/.ui.config.DBPasswordActivity
10-21 23:22:47.896    1439-1720/?                              I/libblt_hw: Library opened (handle = 4, fd = 32)
10-21 23:22:48.196    1862-1896/?                              W/ActivityManager: Activity pause timeout for ActivityRecord{414ad5f8 com.example/.ui.config.DBPasswordActivity}
10-21 23:22:50.398    1462-1789/?                              D/ADM: devset:282    STATUS Close device 'Speaker'
10-21 23:22:57.695    1862-1896/?                              W/ActivityManager: Launch timeout has expired, giving up wake lock!
10-21 23:22:58.206    1862-1896/?                              W/ActivityManager: Activity idle timeout for ActivityRecord{4111e850 com.example/.TestApp}
10-21 23:23:03.791    1462-1788/?                              D/ADM: devset:414    STATUS Open device 'Speaker', 44100 Hz, format=2, 3 x 6144 bytes bufs
10-21 23:23:03.801  17043-17043/com.example            I/Process: Sending signal. PID: 17043 SIG: 9
10-21 23:23:03.811   1862-18347/?                              I/ActivityManager: Process com.example (pid 17043) has died.
10-21 23:23:03.821    1862-2211/?                              I/WindowManager: WIN DEATH: Window{41609620 com.example/com.example.ui.config.DBPasswordActivity paused=false}
10-21 23:23:03.831    1439-1892/?                              I/libblt_hw: Library closed (handle = 0, fd = 11)
10-21 23:23:03.831    1862-2816/?                              I/WindowManager: WIN DEATH: Window{4158a788 com.example/com.example.TestApp paused=false}
10-21 23:23:03.841   1862-18347/?                              W/ActivityManager: Force removing ActivityRecord{4111e850 com.example/.TestApp}: app died, no saved state
10-21 23:23:03.952    1439-1720/?                              I/libblt_hw: Library opened (handle = 0, fd = 11)
10-21 23:23:03.982    1462-1788/?                              E/ENSWrapper: return OMX_ErrorNotImplemented - GetExtensionIndex OMX.ST.AFM.pcmprocessing.transducer_equalizer h=0x0027f8e8  cParameterName=STE.ADM IndexType=unknown OMX_INDEXTYPE [ 0x00000002 ]
10-21 23:23:04.012    1862-2210/?                              W/InputManagerService: Got RemoteException sending setActive(false) notification to pid 17043 uid 10155
10-21 23:23:04.082    1439-1720/?                              I/libblt_hw: Library closed (handle = 4, fd = 32)
10-21 23:23:04.172    1462-1788/?                              D/ADM: devset:588    STATUS API LEAVE: Opened new device 'Speaker', handle = 101
10-21 23:23:07.295    1462-1789/?                              D/ADM: devset:282    STATUS Close device 'Speaker'

Edit2

database.rawExecSQL("BEGIN IMMEDIATE TRANSACTION;");
database.rawExecSQL("PRAGMA rekey = '"+newPass+"';");
database.close();

接着是

getWritableDatabase(newPass);

失败:

10-24 11:47:44.652    1204-1204/com.example D/example: USING PASSWORD :   aaa
10-24 11:47:44.952    1204-1204/com.example I/Database: sqlite returned: error code = 26, msg = file is encrypted or is not a database
10-24 11:47:44.952    1204-1204/com.example E/Database: CREATE TABLE android_metadata failed
10-24 11:47:44.972    1204-1204/com.example E/Database: Failed to setLocale() when constructing, closing the database
        net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
        at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
        at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2101)
        at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1967)
        at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:900)
        at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:943)
        at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:107)

编辑3 - 解决方案

DB文件在安装时使用空字符串进行加密。

10-21 23:22:46.945  17043-17043/com.example            D/testapp: saveDBPasswordSettings - oldPass: ##
10-21 23:22:46.945  17043-17043/com.example            D/testapp: saveDBPasswordSettings - newPass: #newpass#

4 个答案:

答案 0 :(得分:6)

SQLCipher API Documentation

Rekey不能用于加密未加密的数据库以启动。如果您的用户从空密码更改为非空密码,它将以您描述的方式失败。他们记录了如何加密以前未加密的数据库here

答案 1 :(得分:2)

SQLiteDatabase.rawExecSQL("PRAGMA key = 'old_password';");
SQLiteDatabase.rawExecSQL("PRAGMA rekey = 'new_password';");

答案 2 :(得分:1)

颁发

database.rawExecSQL("BEGIN IMMEDIATE TRANSACTION;");

之前的

database.rawExecSQL("PRAGMA rekey = '"+newPass+"';");

应确保在此期间没有其他数据库连接能够写入数据库。

答案 3 :(得分:0)

请确认您在恢复申请时使用新密码,因为它与SQLiteOpenHelper.getWritableDatabase(…)中的来电相关。