Android Room & SQLCipher:資料庫存取與加密

Photo by Valdemaras D. on Unsplash
Photo by Valdemaras D. on Unsplash
本文章將介紹如何在 Android 中使用 Room 和 SQLCipher 來加密資料庫。

本文章將介紹如何在 Android 中使用 RoomSQLCipher 來加密資料庫。

完整程式碼可以在 下載。

SQLCipher

SQLCipher 是一個可以用密碼加密 SQLite 資料庫的套件。

與 Room 一起使用

SQLCipher 與 Room 的整合相當地好。我們可以很輕易地將它整合到我們的 Android 專案中。如果你不熟悉 Room 的話,請先參照以下文章。

首先,我們要引入 SQLCipher 的 dependency。

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

修改 EmpolyeeDatabase.getInstance() ,讓它可以多接收一個密碼參數。由於 SupportFactory 只接收 ByteArray,所以我們要先將參數 password 轉換成 CharArray。然後再用 SQLiteDatabase.getBytes() 來將 CharArray 轉換成合適的 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
            }
        }
    }
}

最後在 EmployeeListViewModel 裡,我們設定密碼為 1234。這樣就完成了!

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

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

在命令列上存取加密的資料庫

因為除錯的需求,有時候我們可能會想要查看加密的資料庫裡面有哪些資料。SQLCipher 也有提供 command line 的方式來存取資料庫。所以,首先我們要先安裝 SQLCipher 的指令。你可以從這裡下載原始碼,然後編譯並且安裝。如果你的系統是 MacOS 的話,我們可以利用 Homebrew 來安裝,如下。

% brew install sqlcipher

接下來,在 Device File Explorer 中,下載資料庫檔案。記得那三個檔案都要一起下載下來。然後用以下的指令來開啟資料庫,並且輸入密碼,就可以存取資料庫裡的資料了。

% 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
%

結語

Room 搭配 SQLCipher 使用,可以增加資料的安全性。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

You May Also Like
Photo by Hans-Jurgen Mager on Unsplash
Read More

Kotlin Coroutine 教學

Kotlin 的 coroutine 是用來取代 thread。它不會阻塞 thread,而且還可以被取消。Coroutine core 會幫你管理 thread 的數量,讓你不需要自行管理,這也可以避免不小心建立過多的 thread。
Read More