The Basics of SQLCipher for Android

The ToDoCrypt module of the book’s primary sample project contains its own edition of those classes, plus the whole to-do app UI that employs them. In addition, this app adds SQLCipher for Android, in case the user really wants to protect those to-do items.

Adding the Dependency

Zetetic maintains a standard Android AAR artifact, available in Maven Central and its mirrors (e.g., Bintray’s JCenter), using net.zetetic:android-database-sqlcipher as the base Maven coordinates. So, ToDoCrypt adds that library to the roster of libraries that it pulls in via the dependencies closure in the module’s build.gradle file:

    implementation "net.zetetic:android-database-sqlcipher:4.4.2"

Creating and Applying the Factory

That gives us access to a SupportFactory class. This is an implementation of SupportSQLiteHelper.Factory and serves as the “glue” between SQLCipher for Android and clients like Room.

The simplest SupportFactory constructor takes a byte[] that represents the passphrase for the database. This will be used in two cases:

How you get that byte[] for the passphrase is up to you. In this sample, we take a very easy and very lousy approach: hardcoding it. So, we have a PASSPHRASE constant and use that in the SupportFactory constructor:

package com.commonsware.todo.repo

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import net.sqlcipher.database.SupportFactory

private const val DB_NAME = "stuff.db"
private const val PASSPHRASE = "sekr1t"

@Database(entities = [ToDoEntity::class], version = 1)
@TypeConverters(TypeTransmogrifier::class)
abstract class ToDoDatabase : RoomDatabase() {
  abstract fun todoStore(): ToDoEntity.Store

  companion object {
    fun newInstance(context: Context) =
      Room.databaseBuilder(context, ToDoDatabase::class.java, DB_NAME)
        .openHelperFactory(SupportFactory(PASSPHRASE.toByteArray()))
        .build()
  }
}

We pass that SupportFactory to openHelperFactory() on our RoomDatabase.Builder, and from there, Room will take over and integrate with SQLCipher for Android.

Using the Database

The beauty of the SupportSQLite* family of APIs is that, for the most part, Room clients neither know nor care about the actual SQLite implementation. ToDoEntity and ToDoEntity.Store do not need anything special for SQLCipher for Android. Even ToDoDatabase has just the change to add that one openHelperFactory() call — nothing else is affected. ToDoRepository and its clients (e.g., viewmodels) are also unaffected. So, everything that has been covered to date in the book just works, with the added improvement of encryption.

Using the Database… Outside the App

To work with a database encrypted by SQLCipher for Android, you will need a client that has SQLCipher compiled in. SQLCipher databases are portable across platforms, just as SQLite databases are, but plain SQLite clients will not know how to deal with SQLCipher’s encryption scheme. So, for example, neither Android Studio’s Database Inspector nor the sqlite3 binary that is part of Android itself will be able to work with SQLCipher for Android databases.

DB Browser for SQLite, however, does support SQLCipher.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.