Skip to content

Fatal Exception: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: while compiling: select count(*) from sqlite_master #247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
surajnavkudkarpersonal opened this issue Jul 18, 2016 · 62 comments

Comments

@surajnavkudkarpersonal
Copy link

surajnavkudkarpersonal commented Jul 18, 2016

Hi ,

App is getting crashed due to above exception on following two devices
1)\ Device: ASUS_Z00VD
OS Version: 5.1

2)Panasonic P41HD
OS Version:4.4.2

Library version used 3.5.2.

Same crash has occurred on below two devices for the previous version of library also

Fatal Exception: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master;
at net.sqlcipher.database.SQLiteCompiledSql.native_compile(SQLiteCompiledSql.java)
at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
at net.sqlcipher.database.SQLiteCompiledSql.(SQLiteCompiledSql.java:64)
at net.sqlcipher.database.SQLiteProgram.(SQLiteProgram.java:83)
at net.sqlcipher.database.SQLiteQuery.(SQLiteQuery.java:49)
at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1762)
at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1727)
at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2344)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1091)
at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1154)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:162)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:129)
at com.xxx.xxx.database.DBOperation.getDatabase(DBOperation.java:37)
at com.xxx.xxx.database.DBOperation.endTransaction(DBOperation.java:58)

@developernotes
Copy link
Member

Hi @suraj9781

Are you able to reproduce this issue within the SQLCipher for Android test suite?

@draak567
Copy link

We are getting this too. For us it happens when the app is killed by Android or the user, after a large commit. In our case we have some migration code that runs to upgrade a 2.x database to 3.x. Part of that migration involves copying some large tables to change their schema (the migration is all inside a single transaction in the onUpgrade function of the database helper).

If you kill the app within a few minutes of that code running, on next start of the app you get that exception when it tries to open the database. We're working on tracking this down further.

@developernotes
Copy link
Member

Hi @draak567

You mention you are upgrading from 2.x to 3.x, is it correct that you mean you are upgrading the SQLCipher database format? If so, and you are receiving an error attempting to open the connection after you have cancelled the upgrade, it is possible the file format migration has not completed. If that is the case, you would need to adjust the KDF iteration length to 4000 to be compatible with a 2.x format. Can you share the upgrade logic you are using?

@draak567
Copy link

@developernotes it's basically something like this:

  1. Open a .db file from 2.x using a standard helper.
  2. Set KDF iteration to 4000 in preKey hook
  3. PRAGMA cipher_migrate in postKey hook (I checked the result and it's 0)
  4. onUpgrade gets called on the helper. Move a bunch of tables etc, all seems to work fine.
  5. At this point the database object is usable as long as I don't close it. I've used it for several minutes.
  6. As soon as I call db.close() and reopen it, I can't access it anymore. I don't even need to kill the app, just closing the database breaks it.

What's confusing me is that I have several other databases in this app upgraded with this code and they all work fine except for this one.

By the way I'm not sure if this is normal but for all the other databases I have to always use KDF iteration 4000 even after migration in the pre-key hook. I've read the documentation and it doesn't imply that is needed, but without that I can't open the database files after migration. I'm starting to think maybe cipher_migrate doesn't actually work even through the return value is zero.

@developernotes
Copy link
Member

Hi @draak567

Set KDF iteration to 4000 in preKey hook

How specifically are you setting the KDF iteration? PRAGMA kdf_iter = …; requires a cipher context to exist which would require this operation to run in the postKey(…); event instead. Alternatively, you could use PRAGMA cipher_default_kdf_iter = …; in the preKey(…); scenario. If you are using preKey to invoke PRAGMA kdf_iter = …;, would you try moving that to the postKey(…); and let us know your results?

What's confusing me is that I have several other databases in this app upgraded with this code and they all work fine except for this one.

Can you pull the database off device to further test access of the content via a SQLCipher command line shell?

@draak567
Copy link

Moving to cipher_default_kdf_iter in preKey fixed it (actually that needed to be done anyway because we attach some databases as well).

I'm not quite sure why the previous code seemed to be working for some of the databases but not the others. When I refactored the migration into a single function that opened all of them, migrated them, and closed them immediately, they all started failing without kdf_iter in postKey, or cipher_default_kdf_iter in preKey.

@developernotes
Copy link
Member

Hello @draak567

I'm glad to hear your issue has been resolved, take care!

@surajnavkudkarpersonal
Copy link
Author

surajnavkudkarpersonal commented Aug 5, 2016

When we changed code to change password of database from mDatabase.changePassword();
to

mDatabase.rawExecSQL("PRAGMA key='" + SqliteHelper.KEY + "';");
mDatabase.rawExecSQL("PRAGMA rekey = '" + pNewPwd + "';");

We observed only one crash.

OS Version: 5.1.1
Device: vivo V3
RAM Free: 49.2%
Disk Free: 87.5%

. Crashed: AsyncTask #3: 0 0 0x0000000000000000
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)

Fatal Exception: java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master;
at net.sqlcipher.database.SQLiteCompiledSql.native_compile(SQLiteCompiledSql.java)
at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
at net.sqlcipher.database.SQLiteCompiledSql.(SQLiteCompiledSql.java:64)
at net.sqlcipher.database.SQLiteProgram.(SQLiteProgram.java:83)
at net.sqlcipher.database.SQLiteQuery.(SQLiteQuery.java:49)
at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1762)
at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1727)
at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2344)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1091)
at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1154)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:162)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:129)
at com.xxx.xxx.database.DBOperation.getDatabase(DBOperation.java:37)
at com.xxx.xxx.database.DBOperation.endTransaction(DBOperation.java:58)

@developernotes
Copy link
Member

Hi @suraj9781

Is there a reason you are not calling changePassword(…); instead? Have you verified you are attempting to open the database with the new password following the change?

@surajnavkudkarpersonal
Copy link
Author

Yes . Actually, there are 4 transactions which each run sequentially for first three transactions there is no issue but in the fourth transaction, this crash occurs on above 2 devices .

@developernotes
Copy link
Member

Hi @suraj9781

Are you trying to change the password to the database while another transaction is occurring? Also, why are you not using the changePassowrd(…); function?

@supervital
Copy link

Hello @developernotes ,

I have the similar exception (SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master). But, when I have migrated from 3.3.1-1 to 3.5.3 version. Nothing was changed.

What is the problem ?

Thanks.

@developernotes
Copy link
Member

Hi @supervital

Would you pull the database off your device/emulator and attempt to access the content with the SQLCipher command line shell? Are you certain you were providing the correct password to the database?

@supervital
Copy link

supervital commented Aug 10, 2016

Yes, the password is correct. I just changed the version in build.gradle.

I haven't tried to open encrypted database ,but with password "" it works.

Also, when I change back to 3.3.1-1 version, app works.

@developernotes
Copy link
Member

I haven't tried to open encrypted database

Please let us know the results of pulling the database off device/emulator and attempting to access the content.

but with password "" it works.

Is that with a new database, or an existing database?

@supervital
Copy link

but with password "" it works.
Is that with a new database, or an existing database?

with an existing db.

There is next scenario: without a password (getReadableDatabase("")) migration from 3.3.1-1 to 3.5.3 version works! Database is ok. Everything works!

But with a password after upgrading to 3.5.3 ver. app crashes with the Exception.

I will try to get access to the content of encrypted database, later. But I think is everything ok with the database.

Thanks.

@surajnavkudkarpersonal
Copy link
Author

Hello @developernotes

Are you trying to change the password to the database while another transaction is occurring?

No

Also, why are you not using the changePassowrd(…); function?

We were using this functions but there were crashes reported on many devices so we tried changing it to mDatabase.rawExecSQL("PRAGMA key='" + SqliteHelper.KEY + "';");
mDatabase.rawExecSQL("PRAGMA rekey = '" + pNewPwd + "';");

@supervital
Copy link

supervital commented Aug 11, 2016

Hello,

I found the problem!

So, there is next issue: the password is encrypted with the XOR algorithm. On 3.3.1-1 it works, but on 3.5.3 it crashes if the pass is encrypted with the algorithm.

How can it be fixed, or should I create a workaround using changePassowrd(…); function ?

Thanks.

@developernotes
Copy link
Member

Hi @supervital

Can you provide an test of the scenario that fails for you as a test within the SQLCipher for Android test suite, we would be happy to look into a reproducible example. Thanks!

@developernotes
Copy link
Member

Hi @suraj9781

Actually, there are 4 transactions which each run sequentially for first three transactions there is no issue but in the fourth transaction, this crash occurs on above 2 devices .

Where does the password change occur with regard to these 4 transactions, is it before, during or after?

We were using this functions but there were crashes reported on many devices so we tried changing it to mDatabase.rawExecSQL("PRAGMA key='" + SqliteHelper.KEY + "';");
mDatabase.rawExecSQL("PRAGMA rekey = '" + pNewPwd + "';");

If you have already keyed the database, executing a PRAGMA key = ….; again is not needed.

@supervital
Copy link

Can you provide an test of the scenario that fails for you as a test within the SQLCipher for Android test suite, we would be happy to look into a reproducible example. Thanks!

Yes, I can. So, I need to install the test application, next I have to reproduce the issue and finally run a test on the test app ? Is it correct ?

@developernotes
Copy link
Member

Hi @supervital

You would need to fork the test suite, create a new test, add it to the runner and then you can verify the behavior on device/emulator. Please then send a pull request and we will take a look into it further. Thanks!

@surajnavkudkarpersonal
Copy link
Author

surajnavkudkarpersonal commented Aug 12, 2016

Hi @developernotes

Where does the password change occur with regard to these 4 transactions, is it before, during or after?

Before the start of 1st transaction

@developernotes
Copy link
Member

Hi @suraj9781

We would be happy to look into it further if you can provide a unit test within the test suite that reproduces the error you are seeing. Thanks!

@YuriyWozniak
Copy link

YuriyWozniak commented Aug 23, 2016

Hello, guys.

Actually, I have found the reason of issue mentioned by @supervital .

Database was encrypted with unique key, containing chars like (int)[] [80, 46, 0, 30, 44, 8, 1 ... ]
As can be seen, it contains zero-byte char. Java stores these chars in modified UTF-8 encoding, so chars under 0x0080 are stored as single-byte compatible, however \u0000 char contains from two bytes.

I noticed the commit changing the key passing logic here 3f36025 with change of void native_key_char(JNIEnv* env, jobject object, jcharArray jKey) method.

Native methods converting jcharArray to char* used to call
- jchar *key = env->GetCharArrayElements(jKey, 0);
- jsize sz = env->GetArrayLength(jKey);
- char password[sz + 1];
- for(idx = 0; idx < sz; idx++){
- password[idx] = (char)key[idx];
}
- password[sz] = '\0';

but now

jsize sz = env->GetArrayLength(jKey);
+ jchar* jKeyChar = env->GetCharArrayElements(jKey, &arrayIsCopy);
+ jstring key = env->NewString(jKeyChar, sz);
+ const char* password = env->GetStringUTFChars(key, JNI_FALSE);
+ int password_sz = env->GetStringUTFLength(key);

As described in Oracle documentation,

GetStringUTFLength
jsize GetStringUTFLength(JNIEnv *env, jstring string);
Returns the length in bytes of the modified UTF-8 representation of a string.

so, zero-byte char is parsed into two bytes.

Also, tip from the book by the following link advices to use native methods without 'UTF'
https://books.google.com.ua/books?id=kELcexu0pAcC&pg=PA542&lpg=PA542&dq=GetStringUTFLength+GetArrayLength+difference&source=bl&ots=SzCTMpSd7V&sig=1M7b7_Wnx5pL9EBnf_a8WNdthng&hl=en&sa=X&ved=0ahUKEwiF1YnrqNfOAhUGyRQKHZ5pALIQ6AEILzAD#v=onepage&q=GetStringUTFLength%20GetArrayLength%20difference&f=false

Thus, it is impossible to even rekey the existing DB using sqlcipher:3.5+

I have verified the conclusion. Without zero-byte char sqlitecipher versions are compatible. With \u0000 char they are not.

Could you please give some advice how to migrate into updated sqlcipher without regression?

Thank you in advance.

@developernotes
Copy link
Member

Hello @YuriyWozniak, @supervital,

Thank you for providing some additional context around the issue you are seeing. Would you mind sharing how you are sourcing the key material that is causing this situation to occur? We are currently reviewing a possible solution. Thanks!

@YuriyWozniak
Copy link

Hello, @developernotes ,

Thank for your feedback

Algorithm looks like next:

// input is a looong alphanumeric password
public static char[] XorCharArray(String input) {
    String secret = generateSecret(); // just an alphanumeric dynamic string
    char[] arr = new char[input.length()];
    for (int i = 0; i < input.length(); i++) {
    // some kind of xor
        char chr = ((char) (input.charAt(i) ^ secret.charAt(i % secret.length())));
        arr[i] = chr;
    }
    return arr;
}
...
readableDatabase = [SQLiteOpenHelper].getReadableDatabase(XorCharArray(DATABASE_PASSWORD));

...
Exception here SQLiteException: file is encrypted or is not a database:
...

In case when input.charAt() == secret.charAt(), xor char, char = 0. That`s why zero char is present.

Well... Algorithm looks a bit legacy and tricky, however, we are already using keys generated with it as zero-char is allowed to use in key.

Thanks for your support.

@sjlombardo
Copy link
Member

Hello @YuriyWozniak - could you provide some additional details about how generateSecret() works and the contents of DATABASE_PASSWORD? Is it possible for either of those to return non-ASCII characters (i.e. with a numeric value > 127)?

@YuriyWozniak
Copy link

YuriyWozniak commented Aug 24, 2016

Hello, @sjlombardo .

Sure, if it can help somehow.

DATABASE_PASSWORD is just an ASCII constant, e.g. like

String DATABASE_PASSWORD = "!dR|u7WTgCiw"TmVJH2?zm+kH&FLl,KDEw";

generateSecret is also ASCII string as concatenation of some unique identifiers.

private static String generateSecret() {
return String.valueOf(A) + ... + android.app.Activity.ACTIVITY_SERVICE + Build.MANUFACTURER + Build.SERIAL + Build.MODEL + ...;
}

Is it possible for either of those to return non-ASCII characters (i.e. with a numeric value > 127)?

theoretically, yes. But practically we weren`t observing such a case.

Maybe it would be better to change the algo, or for example, base64 the final key. However, we are using the mentioned approach for now :(

Thanks for support.

@surajnavkudkarpersonal
Copy link
Author

Hello, @sjlombardo ,

In my case, i am using UDID as password

String lNewDBPassword = Secure.getString(pContext.getContentResolver(),
Secure.ANDROID_ID);

@developernotes
Copy link
Member

Hi @girishcsed,

Can you verify the database is being provided the same password each time, including when the user returns from the Settings application? Can you verify you are able to access the database from the SQLCipher command line shell with the same password you are providing within the application? Thanks!

@girishcsed
Copy link

Hi,
Thanks for your response. Actually it crashes even before entering the password. I verified that database is being encrypted and im able to access database after giving the password.
My guess is it crashes whenever i do this

public PatientDBAdapter(Context context) {
        db = DBHelper.getInstance(context,Utilities.getDatabaseName(context)).getWritableDatabase(MainActivity.getKey());
        this.context = context;

```}

@developernotes
Copy link
Member

Hi @girishcsed

Can you verify you are calling SQLiteDatabase.loadLibs(this); before any interaction occurs within the SQLiteDatabase API?

@girishcsed
Copy link

Yes, made sure that im calling SQLiteDatabase.loadLibs(this); before making any interactions with SQLiteDatabase.

@developernotes
Copy link
Member

Hello @girishcsed

We would be happy to look into this further if you can provide a reproducible test case within the SQLCipher for Android test suite. Thanks!

@girishcsed
Copy link

Hello,
I tried to run SQLCipher Test Suite on a device and got "OK" for all Tests. But when i go to the background from the app, it crahes with the following logs:

09-14 16:08:02.726 21679-21768/net.zetetic E/Database: Failed to setLocale() when constructing, closing the database
                                                       net.sqlcipher.database.SQLiteException: file is encrypted or 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:83)
                                                           at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:49)
                                                           at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
                                                           at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1772)
                                                           at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1737)
                                                           at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2354)
                                                           at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1101)
                                                           at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1164)
                                                           at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:162)
                                                           at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:227)
                                                           at net.zetetic.tests.ReadableWritableInvalidPasswordTest.execute(ReadableWritableInvalidPasswordTest.java:81)
                                                           at net.zetetic.tests.SQLCipherTest.run(SQLCipherTest.java:35)
                                                           at net.zetetic.tests.TestSuiteRunner.runSuite(TestSuiteRunner.java:40)
                                                           at net.zetetic.tests.TestSuiteRunner.doInBackground(TestSuiteRunner.java:20)
                                                           at net.zetetic.tests.TestSuiteRunner.doInBackground(TestSuiteRunner.java:12)
                                                           at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                           at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                           at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                           at java.lang.Thread.run(Thread.java:818)
09-14 16:08:02.726 21679-21768/net.zetetic E/SQLiteOpenHelper: Couldn't open test.db for writing (will try read-only):
                                                               net.sqlcipher.database.SQLiteException: file is encrypted or 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:83)
                                                                   at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:49)
                                                                   at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
                                                                   at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1772)
                                                                   at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1737)
                                                                   at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2354)
                                                                   at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1101)
                                                                   at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1164)
                                                                   at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:162)
                                                                   at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:227)
                                                                   at net.zetetic.tests.ReadableWritableInvalidPasswordTest.execute(ReadableWritableInvalidPasswordTest.java:81)
                                                                   at net.zetetic.tests.SQLCipherTest.run(SQLCipherTest.java:35)
                                                                   at net.zetetic.tests.TestSuiteRunner.runSuite(TestSuiteRunner.java:40)
                                                                   at net.zetetic.tests.TestSuiteRunner.doInBackground(TestSuiteRunner.java:20)
                                                                   at net.zetetic.tests.TestSuiteRunner.doInBackground(TestSuiteRunner.java:12)
                                                                   at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                                   at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                   at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                                   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                   at java.lang.Thread.run(Thread.java:818)
09-14 16:08:02.727 21679-21768/net.zetetic E/Database: Failed to setLocale() when constructing, closing the database
                                                       net.sqlcipher.database.SQLiteException: file is encrypted or 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:83)
                                                           at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:49)
                                                           at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
                                                           at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1772)
                                                           at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1737)
                                                           at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2354)
                                                           at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1101)
                                                           at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:993)
                                                           at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:249)
                                                           at net.zetetic.tests.ReadableWritableInvalidPasswordTest.execute(ReadableWritableInvalidPasswordTest.java:81)
                                                           at net.zetetic.tests.SQLCipherTest.run(SQLCipherTest.java:35)
                                                           at net.zetetic.tests.TestSuiteRunner.runSuite(TestSuiteRunner.java:40)
                                                           at net.zetetic.tests.TestSuiteRunner.doInBackground(TestSuiteRunner.java:20)
                                                           at net.zetetic.tests.TestSuiteRunner.doInBackground(TestSuiteRunner.java:12)
                                                           at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                           at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                           at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                           at java.lang.Thread.run(Thread.java:818)
09-14 16:08:02.728 21679-21768/net.zetetic V/Zetetic: EXPECTED RESULT: SQLiteException when opening readable encrypted database with blank password char array OK
                                                      net.sqlcipher.database.SQLiteException: file is encrypted or 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:83)
                                                          at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:49)
                                                          at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
                                                          at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1772)
                                                          at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1737)
                                                          at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2354)
                                                          at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1101)
                                                          at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:993)
                                                          at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:249)
                                                          at net.zetetic.tests.ReadableWritableInvalidPasswordTest.execute(ReadableWritableInvalidPasswordTest.java:81)
                                                          at net.zetetic.tests.SQLCipherTest.run(SQLCipherTest.java:35)
                                                          at net.zetetic.tests.TestSuiteRunner.runSuite(TestSuiteRunner.java:40)
                                                          at net.zetetic.tests.TestSuiteRunner.doInBackground(TestSuiteRunner.java:20)
                                                          at net.zetetic.tests.TestSuiteRunner.doInBackground(TestSuiteRunner.java:12)
                                                          at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                          at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                          at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                          at java.lang.Thread.run(Thread.java:818)

@developernotes
Copy link
Member

Hello @girishcsed,

The log messages are often expected within the SQLCipher for Android test suite as they recreate certain scenarios where an exception might occur.

@girishcsed
Copy link

net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master; is the exact same crash that our app users are getting. I cant reproduce this crash but our analytics show that there have been a lot of crashes with the above logs.

@girishcsed
Copy link

Is it possible to handle such type of exceptions on the library?

@developernotes
Copy link
Member

Hi @girishcsed,

Your application can catch the SQLiteException that occurs, you should also consider reviewing your application to see if there is a scenario where you are attempting to open a database with an invalid password.

@girishcsed
Copy link

I made sure that we are opening the database with correct password. I'll handle all sqlite exceptions on our App. Thanks for your help.

@YuriyWozniak
Copy link

Hello, guys. Hello, @developernotes.

Noticed the updated release 3.5.4. We had tested it, and issue with zero-byte symbol in db key looks fixed.

Many thanks for your support!

@developernotes
Copy link
Member

Hello @YuriyWozniak,

Thank you for getting back to us, we are happy to hear the latest release has addressed the issue you were seeing. Take care!

@jcb316733855
Copy link

I have met the same issue, and this issue was fixed on 3.5.4? we can't reproduce this issue on our devices, this is the crash log from user:

#4366 09-25 14:58:37.829 7200 E Database Failed to setLocale() when constructing, closing the database
#4367 09-25 14:58:37.829 7200 E Database net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master;
#4368 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
#4369 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteCompiledSql.compile(Unknown Source)
#4370 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteCompiledSql.(Unknown Source)
#4371 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteProgram.(Unknown Source)
#4372 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteQuery.(Unknown Source)
#4373 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteDirectCursorDriver.query(Unknown Source)
#4374 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(Unknown Source)
#4375 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteDatabase.rawQuery(Unknown Source)
#4376 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(Unknown Source)
#4377 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteDatabase.openDatabase(Unknown Source)
#4378 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(Unknown Source)
#4379 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(Unknown Source)
#4380 09-25 14:58:37.829 7200 E Database at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(Unknown Source)

@developernotes
Copy link
Member

Hi @jcb316733855

What version of SQLCipher for Android are you using? If you are not on 3.5.4, would you try that as it is the latest build. Thank!

@kameshkarthik
Copy link

Hello,
I am having the same crash, but it rather occurs for a fresh install of the application on only HTC One Android 6.0 . I have tried the test-suite , it works perfectly for the default password "test", whereas when I change the password the following tests fail

  1. Cipher Migrate Test
  2. Attach Existing Database Test
  3. Migrate Database 1.x to Current Test
  4. Migrate Database 1.x to Current with user_version
  5. Migrate from modified UTF-8 to UTF-8 with null test

I am on 3.5.4.
Could you please give me some advice on how to proceed further. I am stuck and am unable to produce the crash with my application.

@developernotes
Copy link
Member

Hi @kameshkarthik

Are you able to create a test within the test suite that consistently replicates the behavior you are seeing? You can not change the password of the tests you listed above, those tests utilize sample databases included with the test suite where a specific password was used.

@chrissickler
Copy link

@developernotes my database seemed to be working with the input password "password" but now is not working and throwing the same exceptions as above. I am building an app that when starts up, asks for a passphrase, then using that, I am trying to open the database and get what is inside it, and store the information into an array.

Any help would be awesome!

@developernotes
Copy link
Member

Hi @chrissickler

A few additional follow up questions:

  • Is this something you can replicate in the SQLCipher for Android test suite?
  • What specific exception do you receive? There are a few stack traces above.
  • What version of SQLCipher for Android are you currently using?

@chrissickler
Copy link

I actually stepped thru my code and found that I was stuck in a while loop, trying to endlessly access data from the database. I believe I am using 3.5.6 or whatever is the latest version. Thank you for the response though!

@developernotes
Copy link
Member

@chrissickler

We are glad to hear you resolved your error. Take care!

@nirmalspeed
Copy link

Hello,

I am getting this exception when calling getWritableDatabase on 3.5.7 when upgrading android app from an older version to this latest version.

The database from the older version is readable just fine when pulling it off a device so not sure whats causing it.

Thanks in advance.

@developernotes
Copy link
Member

Hi @nirmalspeed

Would you please open a separate Github issue, or posting on our discuss site with further details regarding your crash. Also, please note what version of SQLCipher was used to create the original database file and any other runtime specific configurations you have. Thanks!

@lavan80
Copy link

lavan80 commented Feb 5, 2018

Hi @developernotes
I am getting exception :
net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master;
at net.sqlcipher.database.SQLiteCompiledSql.native_compile()(SQLiteCompiledSql.java:-2)
at net.sqlcipher.database.SQLiteCompiledSql.compile()(SQLiteCompiledSql.java:91)
at net.sqlcipher.database.SQLiteCompiledSql.()(SQLiteCompiledSql.java:64)
at net.sqlcipher.database.SQLiteProgram.()(SQLiteProgram.java:83)
at net.sqlcipher.database.SQLiteStatement.()(SQLiteStatement.java:39)
at net.sqlcipher.database.SQLiteDatabase.compileStatement()(SQLiteDatabase.java:1556)
at net.sqlcipher.database.SQLiteDatabase.updateWithOnConflict()(SQLiteDatabase.java:2128)
at net.sqlcipher.database.SQLiteDatabase.update()(SQLiteDatabase.java:2075)
at com.positionin.model.provider.SelectionBuilder.update()(SelectionBuilder.java:133)
at com.positionin.model.provider.DataProvider.update()(DataProvider.java:369)
at android.content.ContentProvider$Transport.update()(ContentProvider.java:356)
at android.content.ContentResolver.update()(ContentResolver.java:1409)
I use 3.5.4@aar version of SQLCipher and have crush on BlackBerry device. In this device user do clean install.
Thanks in advance.

@developernotes
Copy link
Member

Hi @lavan80

Does this error always occur for you? Are you able to reproduce this issue consistently? Would you try upgrading to the latest version, currently 3.5.9 and let us know if you are still receiving the error message?

@lavan80
Copy link

lavan80 commented Feb 6, 2018

HI @developernotes
Yes this occur all time. Stack trace i got from our error tracker. I don't have this device. This device of our customer.

@developernotes
Copy link
Member

Hi @lavan80

Unfortunately, without additional information such as what SQL statement is being executed and further details such as the device and Android OS version, we are not able to provide any additional information regarding the stack track that your provided above.

Again, we would recommend updating to the latest version of SQLCipher for Android, currently at 3.5.9 and testing to see if the behavior continues or is resolved. If the behavior continues, we would need additional information to investigate it further.

@sqlcipher sqlcipher locked and limited conversation to collaborators Feb 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests