Accessing and Encrypting Database with Room and SQLCipher on Android

Photo by Valdemaras D. on Unsplash
Photo by Valdemaras D. on Unsplash
This article will introduce how to use Room and SQLCipher to encrypt the databases.

This article will introduce how to use Room and SQLCipher to encrypt the databases.

The complete code for this chapter can be found in .

SQLCipher

SQLCipher is a library that encrypts SQLite databases with passwords.

Using it with Room

SQLCipher integrates with Room very well. We can easily integrate it into our Android projects. If you are not familiar with Room, please refer the article below.

First, we have to add the dependency of SQLCipher.

dependencies {
    def sqlcipher_version = "4.5.0"
    implementation "net.zetetic:android-database-sqlcipher:$sqlcipher_version"
}

Modify EmpolyeeDatabase.getInstance(), so that it can receive one more parameter called password. Since SupportFactory only receives ByteArray, we need to convert parameter password to CharArray. Then use SQLiteDatabase.getBytes() to convert CharArray to a suitable ByteArray.

import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SupportFactory

@Database(entities = [Employee::class], version = 1)
@TypeConverters(Converters::class)
abstract class EmployeeDatabase : RoomDatabase() {
    abstract fun dao(): EmployeeDao

    companion object {
        @Volatile
        private var INSTANCE: EmployeeDatabase? = null

        fun getInstance(context: Context, path: String, password: String): EmployeeDatabase {
            return INSTANCE ?: synchronized(this) {
                val supportFactory = SupportFactory(SQLiteDatabase.getBytes(password.toCharArray()))
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    EmployeeDatabase::class.java,
                    path,
                )
                    .openHelperFactory(supportFactory)
                    .build()
                INSTANCE = instance
                instance
            }
        }
    }
}

Finally in EmployeeListViewModel, we set the password to 1234. This is all!

class EmployeeListViewModel : ViewModel() {
    private lateinit var database: EmployeeDatabase

    fun initDatabase(context: Context) {
        val path = context.getDatabasePath("employee")
        database = EmployeeDatabase.getInstance(context, path.absolutePath, "1234")
    }
}

Accessing Encrypted Databases from the Command Line

Because of the needs of debugging, sometimes we may want to see what data is stored in the encrypted database. SQLCipher also provides a command line to access the database. So, first of all we have to install the SQLCipher command. You can download the source code from here, then compile and install it. If your system is MacOS, we can install it with Homebrew, as follows.

% brew install sqlcipher

Next, in Device File Explorer, download the database files. Remember to download all 3 files together. Then use the following command to open the database, and enter the password, you can access the data in the database.

% ls
employee employee-shm employee-wal
% sqlcipher employee
SQLite version 3.37.2 2022-01-06 13:25:41 (SQLCipher 4.5.1 community)
Enter ".help" for usage hints.
sqlite> PRAGMA key = "1234";
ok
sqlite> .tables
employees          room_master_table
sqlite> select * from employees;
David|FULL_TIME|1649824497125|1
Wayne|FULL_TIME|1649824502095|2
Peter|FULL_TIME|1649824509877|3
sqlite>.quit
%

Conclusion

Room makes it easy to access databases, compared to ORMLite. Moreover, it also integrates suspend function. With SQLCipher, we can increase the security for the data.

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like
Photo by Willian Justen de Vasconcellos on Unsplash
Read More

Android Looper and Handler Tutorial

Looper and Handler are one of the Android core components, and many high-level components are built on top of them. Understanding them helps us understand how some core components work. This article will introduce Looper and Handler and related components.
Read More