SQLite Android Bindings

Documentation
Login

Using The SQLite Encryption Extension

The The SQLite Encryption Extension provides an easy way to create, read and write encrypted database files. It may be used with the SQLite Android bindings to add encrypted database capability to any application.

Building a SEE Enabled Version

Unless you are using a pre-built aar file to use the SEE extension with the SQLite Android bindings you will need to build a custom version, either as a custom aar file or by directly integrating the code with the application.

To do this, follow the instructions linked above. Except, before running the ndk-build command to build the native libraries:

  1. Replace the sqlite3.c and sqlite3.h files with the SEE enable versions (i.e. the concatenation of sqlite3.c and see.c - refer to the link above for details).
  2. Edit the Android.mk file so as to uncomment the second of the two lines reproduced below:
      # If using SEE, uncomment the following:
      # LOCAL_CFLAGS += -DSQLITE_HAS_CODEC
    

Application Code Notes

After opening or creating an encrypted database, the application must immediately execute a PRAGMA to configure the encryption key. This must be done before any other database methods are called. For example:

  import org.sqlite.database.sqlite.SQLiteDatabase;

    ...

  SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("my.db", null);
  db.execSQL("PRAGMA key = 'secretkey'");

Or, if you are using the SQLiteOpenHelper helper class, the PRAGMA must be the first thing executed within the onConfigure() callback. For example:

  import org.sqlite.database.sqlite.SQLiteDatabase;
  import org.sqlite.database.sqlite.SQLiteHelper;

    ...

  class MyHelper extends SQLiteOpenHelper {
    ...
    void onConfigure(SQLiteDatabase db){
      db.execSQL("PRAGMA key = 'secretkey'");
    }
    ...
  }

Refer to the SEE documentation for further details regarding encryption keys.

Aside from supporting encrypted databases, SEE-enabled builds behave differently in two more respects:

  1. The SQLiteDatabase.enableWriteAheadLogging() method does not enable connection pooling. It is not possible for connection pooling to be used with a SEE-enabled build (even if the database is unencrypted).

  2. In Android, if database corruption is encountered, or if an attempt is made to open a file that is not an SQLite database, the default behaviour is to delete the file and create an empty database file in its place. In a SEE-enabled build, the default behaviour is to throw an exception.

    The reason for this is that supplying an incorrect encryption key is indistinguishable from opening a file that is not a database file. And it seems too dangerous to simply delete the file in this case.

    The default behaviour can be overriden using the DatabaseErrorHandler interface.