Changing database password fails
Asked Answered
A

4

3

My app has an SQLCipher password protected database. My activity that allows to change password:

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

After executing it, trying to access database again I get :

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)

Followed by:

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)

What is going on? Execution log :

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'

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

Followed by :

getWritableDatabase(newPass);

Fails with:

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)
Adversative answered 21/10, 2013 at 15:57 Comment(2)
Though you are passing oldPass to openDatabase(), try calling PRAGMA KEY (with oldPass again) before PRAGMA REKEY.Glacial
Hello NuSkooler. Did that before and did not work either.Adversative
P
7

SQLCipher API Documentation

Rekey cannot be used to encrypt a database that is not encrypted to start. If your users are changing from an empty password to a non-empty password, it will fail in much the way you describe. They document how to encrypt a previously unencrypted database here.

Peruzzi answered 27/10, 2013 at 21:4 Comment(1)
that is actually a good point. The original DB encrypted files were using an empty password. Completely forgot about this, so thanks for pointing that out.Adversative
V
3
SQLiteDatabase.rawExecSQL("PRAGMA key = 'old_password';");
SQLiteDatabase.rawExecSQL("PRAGMA rekey = 'new_password';");
Vergne answered 10/10, 2014 at 5:58 Comment(0)
F
1

Issuing

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

prior to the

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

should ensure that no other database connection would be able to write to the database in the meantime.

Fetishist answered 23/10, 2013 at 18:26 Comment(3)
Is the encrypted DB, that you're trying to rekey, one that you've created with the same version of SQLCipher? If you're working with SQLCipher 2.0 against a 1.x database, SQLCipher 2 can't operate on version 1.1.x databases by default. Thus, in order to provide backward compatibility with SQLCipher 1.1.x, PRAGMA cipher_use_hmac can be used to disable the HMAC functionality on specific databases. [link]sqlcipher.net/sqlcipher-api/#cipher_use_hmacFetishist
Is was the same version of SQLCipher. Problem was the original DB files were being encrypted using an empty password. Thanks for your commentAdversative
how to stop the transaction..as after changing the password..if I try to insert some data in database...i got the error cannot start a transaction within a transaction: BEGIN EXCLUSIVE; but if I don't use database.rawExecSQL("BEGIN IMMEDIATE TRANSACTION;"); i don't get any error while inserting data..Biweekly
P
0

Please verify you are using the new password when resuming your application as it relates to the call in SQLiteOpenHelper.getWritableDatabase(…).

Pooi answered 21/10, 2013 at 21:25 Comment(1)
Yes, I am sure I'm using the new passwordAdversative

© 2022 - 2024 — McMap. All rights reserved.