[MOD-2523] Encrypted Database: Android: Unable to perform cipher_migrate
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | None |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2020-03-18T01:13:54.000+0000 |
Affected Version/s | n/a |
Fix Version/s | n/a |
Components | Encrypted SQLite DB |
Labels | android, encrypted_database, sqlite |
Reporter | John V Pataki |
Assignee | Gary Mathews |
Created | 2019-05-22T21:33:19.000+0000 |
Updated | 2020-03-18T02:01:03.000+0000 |
Description
Version 3.0.2 of the encrypted database module used sqlcipher v3.5.9 whereas version 3.0.4 of the module uses sqlcipher 4.0.1. Databases downloaded from a server and installed (as part of the way the app functions) that used 3.x sqlcipher need to have the sqlcipher function
cipher_migrate
called for them to be accessed properly in apps using sqlcipher v4.x. Using v3.0.2 of the module works as expected because the cipher version is compatible. Note this issue has been around prior to 3.x to 4.x and will likely be around well after when 4.x goes to 5.x and so on.
cipher_migrate
needs to be called after the key, but before any other operations. Since the Android module calls openOrCreateDatabase at the java level and this method eventually calls [keyDatabase](https://github.com/sqlcipher/android-database-sqlcipher/blob/79bfeedaedfc5329e31c70a47666c9f7eaf20d87/android-database-sqlcipher/src/main/java/net/sqlcipher/database/SQLiteDatabase.java#L2633) which performs a test after it keys the database and consequentially before you are able to call cipher_migrate
at the javascript level, the test fails and the database is not usable from that point on in the db instance. I can confirm that if I grab the database file from the emulator, migrate them on the desktop version of sqlcipher and put them back into the emulator, the app is able to access the database as expected/before.
This could be resolve-able if the other ticket created that I created a few minutes ago is implemented that allows preKey and postKey hooks to be defined (i.e. by defining "PRAGMA cipher_migrate;" in the postKey hook). You can see from the code for [keyDatabase](https://github.com/sqlcipher/android-database-sqlcipher/blob/79bfeedaedfc5329e31c70a47666c9f7eaf20d87/android-database-sqlcipher/src/main/java/net/sqlcipher/database/SQLiteDatabase.java#L2633) that the order of operations is: databaseHook.preKey, keyOperation.run, databaseHook.postKey and then it performs the query test to confirm the key was successful select count(*) from sqlite_master;
. And that the opportunity to insert "PRAGMA cipher_migrate;" into the postKey hook would appear to follow how the sqlcipher library was intended to be used.
Also, the iOS implementation has specifically exposed at the javascript level a way to perform the migration... but nothing is available for Android, so perhaps in addition to customizable preKey and postKey hooks, simply adding the ability to specifically migrate at Android would align it with iOS (the same would then go for the method that allows you to determine if it needs to be migrated).
https://github.com/appcelerator-modules/appcelerator.encrypteddatabase/pull/40 [android.encrypteddatabase-android-3.0.5](https://github.com/appcelerator-modules/appcelerator.encrypteddatabase/releases/tag/android-3.0.5)
Above PR was closed in favor of: https://github.com/appcelerator-modules/appcelerator.encrypteddatabase/pull/41
Hi [~jquick], will the PR 41 you reference actually allow the execution of
PRAGMA cipher_migrate
on a database or some other way of running thecipher_migrate
so that an older database can be migrated and usable in the application? It isn't clear to me by only glancing at it how you get around the core problem identified in this issue.The module has been changed to automatically call
PRAGMA cipher_migrate
every time you open the database file based on your recommendation. You can see the change below. The below closed PR's code change was copied to the other PR. https://github.com/appcelerator-modules/appcelerator.encrypteddatabase/pull/40/files#diff-4d989e0aa980a27bc6f62f4a73e6ca7fAwesome - great that is covered then going forward.
FYI: This was resolved in Android module version 3.1.0 back in October 2019. Sorry about the late response. And the module is currently version 4.0.0 for Titanium 9.0.0. It's been migrated to gradle and it now uses sqlcipher library version 4.3.0.