greenDAO supports encrypted databases to protect sensitive data.
While newer versions of Android support file system encryption, Android itself does not provide encryption for database files. So if an attacker obtains access to a database file (by gaining root access, for example by exploiting a security flaw or tricking the user of a rooted device), the attacker may get access to all data inside that database. Using a password-protected, encrypted database adds an additional layer of security. It prevents an attacker from simply opening the database file.
Using custom SQLite builds
Because Android does not support encrypted databases out of the box, you need to bundle a custom build of SQLite inside your APK. Those custom builds consist of CPU dependent, native code. So your APK size will grow by a couple of MByte. Thus, you should only use encryption if you really need it.
Setting up Database Encryption
greenDAO supports SQLCipher with a binding directly. SQLCipher is a custom build of SQLite using 256-bit AES encryption.
Add the SQLCipher dependency
See the SQLCipher for Android page on how to add SQLCipher to your project.
Make sure to use a subclass of OpenHelper provided in DaoMaster to create your database instance. For example the simple DevOpenHelper, also provided in DaoMaster.
Then, when creating your database instance, just call .getEncryptedWritableDb(<password>) instead of .getWritableDb(). Finally, pass the database to DaoMaster as usual:
DevOpenHelper helper = new DevOpenHelper(this, "notes-db-encrypted.db");
Database db = helper.getEncryptedWritableDb("<your-secret-password>");
daoSession = new DaoMaster(db).newSession();
greenDAO uses a thin abstraction layer for all database interaction, so standard and non-standard SQLite implementations are supported:
- Android’s standard android.database.sqlite.SQLiteDatabase
- SQLCipher’s net.sqlcipher.database.SQLiteDatabase
- Any SQLite compatible database, which can implement org.greenrobot.greendao.database.Database (for example custom builds of SQLite)
This enables you to switch easily from standard to encrypted databases because your code will be the same when targeting DaoSession and individual DAOs.
Unit testing with Robolectric
Database abstraction allows unit testing with Robolectric. Even when your app uses an encrypted database, your tests can use an unencrypted database.
Robolectric implements the standard SQLite API and has no way of loading custom SQLite builds (Android binaries). So for your tests, use .getWritableDb() instead of .getEncryptedWritableDb(<password>) when creating your database instance (see above).
Known issues with SQLCipher
SQLCipher is a custom build of SQLite. Its Android APIs have diverged a bit from the Android system APIs. Here are the issues we noticed (unrelated to greenDAO):
- Exceptions thrown are not of type android.database.SQLException (see SQLcipher issue 223)
- SQLCipher locks much more than recent SQLiteDatabase implementations. This not just reduces concurrency, but also increases the chance to deadlock.
- Android collations (like LOCALIZED) are absent starting with SQLCipher 3.5.0