A sample app that shows how to easily encrypt the room database in an Android app

Overview

About

This repository contains a sample app that shows how to encrypt the room database in an Android app. The password used for encryption is generated on the first use and is saved in the Android EncryptedSharedPreferences. The app is programmed in kotlin. In java it should work in the same way.

The reason I created this repository was that when I wanted to encrypt the database of an Android App, I could only find outdated blog posts and tutorials using deprecated classes and methods. So after I dug through the Android Documentation I came up with a solution that I thought might be helpful to others. So I am sharing this here in a sample App.

Feel free to open a pull request with improvements.

Room Database Without Encryption

The branch no-encryption in this repository contains the source code of the app without the room database being encrypted.

By analyzing the database file with hexdump it is possible to verify that the database is not encrypted.

hexdump -C secret-database.db-wal

Encrypting the Room Database

SQLCipher

SQLCipher for Android adds encryption to a room database. The setup is simple: The following dependency needs to be added to the app's build.gradle file:

implementation 'net.zetetic:android-database-sqlcipher:4.5.0'

In the database class only two lines of code need to be added. A SGLCipher SupportFactory is instantiated and passed to the Room.databaseBuilder:

val factory = SupportFactory(passphrase)
//Room.databaseBuilder( ... )
    .openHelperFactory(factory)
    //.build()

That is already it for the actual encryption. Sadly SQLCipher does not handle the scenario where a password is generated for encryption on the first use of the app and stored encrypted in Android for future use. The SupportFactory constructor needs a passphrase as an argument. So a passphrase has to be generated.

Generating a Passphrase

The class javax.crypto.KeyGenerator provides the means to generate Keys. A simple function to generate a passphrase would look like this:

const val ALGORITHM_AES = "AES"
const val KEY_SIZE = 256

private fun generatePassphrase(): ByteArray {
    val keyGenerator = KeyGenerator.getInstance(ALGORITHM_AES)
    keyGenerator.init(KEY_SIZE)
    return keyGenerator.generateKey().encoded
}

The generated passphrase can be used to create the SQLCipher SupportFactory. But, of course, the passphrase also needs to be saved so the database can be decrypted in the future.

Storing the Key in the EncryptedSharedPreferences

The passphrase can be stored in the EncryptedSharedPreferences. Those preferences can only be accessed by the app that created them and are encrypted by Android.

To do this a reference to the EncryptedSharedPreferences is needed. The classes MasterKey and MasterKey.Builder and this specific create method of EncryptedSharedPreferences are, as the time of writing, the way to do this. Other classes and methods have been deprecated. To use these classes the following dependencies have to be added to the app's build.gradle file:

implementation "androidx.security:security-crypto:1.0.0"
implementation "androidx.security:security-crypto-ktx:1.1.0-alpha03"

A function retrieving the reference to the EncryptedSharedPreferences could look like this:

const val SHARED_PREFS_NAME = "de.krbmr.encryptedroomdb.shared_prefs"

private fun getSharedPrefs(context: Context): SharedPreferences {
    val masterKey =
        MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
            .build()

    return EncryptedSharedPreferences.create(
        context,
        SHARED_PREFS_NAME,
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
}

Two more functions are needed. One to initialize the preference with a newly generated passphrase. And one to retrieve the passphrase from the preference:

const val PREFS_KEY_PASSPHRASE = "PREFS_KEY_PASSPHRASE"

private fun initializePassphrase(context: Context): ByteArray {
    val passphrase = generatePassphrase()

    getSharedPrefs(context).edit(commit = true) {
        putString(PREFS_KEY_PASSPHRASE, passphrase.toString(Charsets.ISO_8859_1))
    }

    return passphrase
}

private fun getPassphrase(context: Context): ByteArray? {
    val passphraseString = getSharedPrefs(context)
        .getString(PREFS_KEY_PASSPHRASE, null)
    return passphraseString?.toByteArray(Charsets.ISO_8859_1)
}

Important to note is that the ByteArray is converted to a String before saving it to the preference. The ISO-8859-1 encoding is used for that because it does not lose information on encoding and decoding.

Now it is possible to call the function getPassphrase in the function createDB to get the passphrase. When the app is used for the first time, null will be returned. In this case the function initializePassphrase needs to be called.

val passphrase = getPassphrase(context) ?: initializePassphrase(context)

The finished kotlin database class can be found here.

By analyzing the database file with hexdump it is now possible to verify that the database is encrypted.

hexdump -C secret-database.db-wal
You might also like...
❤️ A sample Marvel heroes application based on MVVM (ViewModel, Coroutines, LiveData, Room, Repository, Koin)  architecture.
❤️ A sample Marvel heroes application based on MVVM (ViewModel, Coroutines, LiveData, Room, Repository, Koin) architecture.

MarvelHeroes MarvelHeroes is a demo application based on modern Android application tech-stacks and MVVM architecture. Fetching data from the network

The app has got fullscreen Turkey map via Huawei Map. App selects random province and shows it borders on the map than user will try to guess the provinces name.
The app has got fullscreen Turkey map via Huawei Map. App selects random province and shows it borders on the map than user will try to guess the provinces name.

Il Bil App Introduction I will introduce you to how to implement Account Kit, Map Kit, Game Service. About the game: The app has got fullscreen Turkey

The AboutMe app - a demo app that shows information about a person
The AboutMe app - a demo app that shows information about a person

AboutMe The AboutMe app is a demo app that shows information about a person. Name Settable Nickname An image Scrollable information This app demonstra

Android app that shows what happened today in the history.
Android app that shows what happened today in the history.

Today History Android app Master: Develop: Code Coverage: App that shows what happened today in history. Details Written in Kotlin. Android Studio 2.1

Project BlueWeather is an android app that lists the closest locations to you and shows the 7-day weather forecast for the location you select.
Project BlueWeather is an android app that lists the closest locations to you and shows the 7-day weather forecast for the location you select.

Project BLUEWEATHER Description Project BlueWeather is a weather forecast application for android. It lists the locations closest to you. It then prov

Shows how to build a VPN app for Android using leaf: https://github.com/eycorsican/leaf .

aleaf Shows how to build a VPN app for Android using leaf. Dependencies Rust GCC/clang Make SDK NDK LLVM (Windows host only, see below) Building Linux

A reliable android app that shows upcoming fixtures, updated league tables, and top goal scorers in a Premier League and French Ligue 1
A reliable android app that shows upcoming fixtures, updated league tables, and top goal scorers in a Premier League and French Ligue 1

RapidScore Screenshots Table of Contents Description Dependencies API Reference Lessons Learnt Contributing Roadmap Google Playstore License Author In

New version of my Android app that shows you popular movies using themoviedb.org API.
New version of my Android app that shows you popular movies using themoviedb.org API.

New version of my Android app that shows you popular movies using themoviedb.org API. Using Modern Android Develpment skills like Kotlin, Room, Retrofit, Hilt, coroutines, Flow and Jetpack Compose.

An android app that shows you nearby food places

FoodNow An android app that shows you nearby food places Features include Search

Owner
Lenz Karbaumer
Software and space enthusiast
Lenz Karbaumer
KeyCip - an Android app that allows users to encrypt, decrypt and sign text, photos, videos and other files

KeyCip is an Android app that allows users to encrypt, decrypt and sign text, photos, videos and other files. To accomplish this goal, it relie

null 18 Nov 26, 2022
A quiz app built with trivia api. This app was built with mvvm architecture, dagger-hilt, retrofit, room database, and navigation components.

A quiz app built with trivia api. This app was built with mvvm architecture, dagger-hilt, retrofit, room database, and navigation components.

Stephen Odumirin 3 Dec 19, 2022
App demonstrates how to use Room to save, read, update, and delete inventory items in a SQLite database.

Inventory - Solution Code Solution code for Android Basics in Kotlin. Codelab: Android Jetpack - Room. Introduction This app is an Inventory tracking

Google Developer Training 75 Dec 30, 2022
Simple Notes app, MVVM with Google Architectural components Room database, LiveData and ViewModel. Written in Kotlin using androidx libraries

Simple Notes app, MVVM with Google Architectural components Room database, LiveData and ViewModel. Written in Kotlin using androidx libraries. Implemented Firebase Auth and Database, and used Room database

Javokhir Jambulov 3 Aug 1, 2022
Registration validation testing, Room database testing using JUnit4

Notes app Registration details validation testing, Room database testing using JUnit4 ✨ Screenshots Authors Tridev Deka - LinkedIn - Tridev Deka MIT L

Tridev Deka 0 Mar 30, 2022
Shreyas Patil 2.1k Dec 30, 2022
Sample news app using Kotlin, Hilt, Coroutines, Coil, Room, Retrofit

Tech stack & News App libraries Navigation component - navigation graph for navigating and replacing screens/fragments DataBinding - allows to more ea

Mina Mikhail 3 Dec 28, 2021
KotlinRoom - What is Android Room? (Use in Kotlin) is a sample project I created for my article

KotlinRoom Android Room Nedir? (Kotlin'de kullanımı) adlı yazım için oluşturduğu

Elif Çetinkaya 1 Jan 8, 2022