Is there a correct way to check if the user-provided password of SQLCipher is valid on Android?

I am using SQLCipher for Android and trying to determine the correct way to check if the user password is really provided.

My first wish was to simply try to open the database with the given password using the SQLCipher SQLiteOpenHelper.getReadableDatabase(password) implementation, and then catch the SQLiteException that appears.

This works, but the problem is that since the Android API actually wraps the base C calls, it does most of the work for you - in particular, when you open the database using the Android API, it opens the database, launches its own C-level sqlite3_key method (with password provided), then tries to set the locale in the database, is the password provided correctly.

At this point, the Android library is trying to set the locale, and the underlying database throws an "encrypted or non-encrypted database" SQLiteException , which is caught and updated; but before that, an unrelated error is written to the logs, basically saying that the locale cannot be specified and the database is closed (with stack trace enabled). Since this is specifically written in the Android library, I cannot suppress it, leaving an ugly error in the logs that are not really related to my original problem, namely that I passed the wrong password.

Since level C calls are not displayed in the Android library, I canโ€™t just use the method described in the SQLCipher API documentation regarding Key Testing , because I do not have access to open the database directly.

I SQLiteDatabaseHook to use SQLiteDatabaseHook , but as far as I can tell, this precludes my use of SQLiteOpenHelper , which does not seem to make it possible to configure the hook.

Does anyone else know a better way to verify if the SQLCipher database passphrase is decrypted correctly through the Android SQL Encryption API? I would fully expect a method call and check that an exception was thrown - I do not want the operation to try to do external processing (for example, set locale) in the database and write a completely inexpressible error to my logs.

+6
source share
2 answers

SQLCipher for Android does not know that the password you provided is not valid after sqlite3_key called, because the database key is not used until the SQL command is issued on the database following sqlite3_key , for example, setLocale(...) The method you link above. The problem is that providing an invalid key can be just one of the other possible scenarios that might be the problem when the first SQL statement is executed. A corrupt data file, a failed HMAC check, or opening a file without a database can result in the same error message. For a detailed description of this, please view this thread . It is best to catch an exception when trying to open a database and process it accordingly in the client application.

0
source

I have no better way to test it. I just want to provide some code in addition, so when other people watch this, they may find useful snippets of code. At least when I found this question, I would really like to see some code on how to do a check :)

How I do it in android is:

  // Simply get an instance of SQLiteOpenHelper. dbHelperObj = myDatabase.getInstance(this, str_username, version); // Now we try to open the database with the password from the user. try { dbObj = dbHelperObj.getReadableDatabase(str_password); // The only possible error now must be a wrong password. } catch (Exception e) { dbHelperObj.close(); // Do stuff to tell the user he provided a wrong password. } 
0
source

Source: https://habr.com/ru/post/945015/


All Articles