【问题标题】:sqlcipher - Changing DB password failingsqlcipher - 更改数据库密码失败
【发布时间】:2013-10-21 15:57:23
【问题描述】:

对于这个应用程序,我有一个使用密码保护的 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:修改pass并尝试再次打开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'

编辑2

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)

Edit3 - 解决方案

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#

【问题讨论】:

  • 虽然您将 oldPass 传递给 openDatabase(),但请尝试在 PRAGMA REKEY 之前调用 PRAGMA KEY(再次使用 oldPass)。
  • 你好 NuSkooler。以前这样做过,但也没有用。

标签: android sqlite sqlcipher


【解决方案1】:

SQLCipher API Documentation

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

【讨论】:

  • 这实际上是一个好点。原始数据库加密文件使用空密码。完全忘记了这一点,所以感谢您指出这一点。
【解决方案2】:
SQLiteDatabase.rawExecSQL("PRAGMA key = 'old_password';");
SQLiteDatabase.rawExecSQL("PRAGMA rekey = 'new_password';");

【讨论】:

    【解决方案3】:

    发行

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

    之前

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

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

    【讨论】:

    • 您尝试重新加密的加密数据库是您使用相同版本的 SQLCipher 创建的数据库吗?如果您针对 1.x 数据库使用 SQLCipher 2.0,则默认情况下 SQLCipher 2 无法在 1.1.x 版数据库上运行。因此,为了提供与 SQLCipher 1.1.x 的向后兼容性,PRAGMA cipher_use_hmac 可用于禁用特定数据库上的 HMAC 功能。 [链接]sqlcipher.net/sqlcipher-api/#cipher_use_hmac
    • 是同一版本的 SQLCipher。问题是原始数据库文件正在使用空密码进行加密。感谢您的评论
    • 如何停止交易..更改密码后..如果我尝试在数据库中插入一些数据...我收到错误cannot start a transaction within a transaction: BEGIN EXCLUSIVE; 但如果我不使用@987654326 @我在插入数据时没有收到任何错误..
    【解决方案4】:

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

    【讨论】:

    • 是的,我确定我使用的是新密码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 2013-02-06
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多