首頁 > 軟體

Android SQLite資料庫加密的操作方法

2021-09-30 19:00:20

一、前言

SQLite是一個輕量級的、跨平臺的、開源的嵌入式資料庫引擎,也是一個關係型的的使用SQL語句的資料庫引擎,
讀寫效率高、資源消耗總量少、延遲時間少,使其成為行動平臺資料庫的最佳解決方案(如Android、iOS)
但是Android上自帶的SQLite資料庫是沒有實現加密的,我們可以通過Android Studio直接匯出應用建立的資料庫檔案,然後通過如SQLite Expere Personal 這種視覺化工具開啟資料庫檔案進行檢視資料庫的表結構,以及資料,這就導致儲存在SQLite中的資料可以被任何人檢視,如果是一些賬號密碼,或者聊天資料等,那麼我們的應用就面臨著嚴重的安全漏洞隱患;

二、資料庫加密方法

因為Android自帶的SQLite資料庫本身是沒有實現加密的,那我們如何實現對資料庫的加密呢?

(1)對SQLite資料庫的資料進行加密

我們可以在程式中對儲存到資料庫中的資料 進行加密後儲存,然後查詢資料的時候,對查詢的資料進行解密後使用,如果還不希望別人看到資料庫的表結構,我們可以對資料庫名字,表名,表中的欄位名字使用MD5等加密手段加密後再進行操作;
這種方法是可以達到資料庫加密的目的的,但是相對來說操作就比較繁瑣了

(2)使用SQLCipher對SQLite資料庫加密

SQLCipher是基於SQLite基礎之上實現了資料庫加密的開源庫,可以採用第三方的開源框架SQLCipher,SQLCipher是基於原生SQlite資料庫進行擴充套件,實現資料庫整體加密(資料庫檔案加密),提供的資料庫的操作介面,和原生的SQLite資料庫操作介面基本一樣的;我們建立或者開啟資料庫都需要密碼,我們開啟資料庫時的密碼,需要和建立資料庫時的密碼保護一致,否則開啟資料庫時會報錯,提示開啟的檔案不是一個資料庫檔案

net.sqlcipher.database.SQLiteException: file is not a database;

我們匯出的資料庫檔案,通過SQLite Expere Personal這類視覺化工具也是無法直接開啟的;但是可以使用DB Browser for Sqlite這個資料庫檢視工具進行檢視,檢視的時候輸入建立資料庫時使用的加密密碼

SQLCipher的特點:

SQLCipher 佔用空間小,效能好,因此非常適合保護嵌入式應用程式資料庫,非常適合移動開發。

(1)極快的效能,加密開銷低至 5-15%

(2)資料庫檔案中的資料 100% 已加密,是對所有資料檔案,包括資料檔案和快取、結構檔案等等進行加密。

(3)使用良好的安全實踐(CBC 模式、金鑰派生),加密演演算法是256位 AES 在 CBC 模式

(4)使用 OpenSSL 加密庫提供的演演算法

在Android中整合SQLiteCipher:

-新增SQLiteCipher的依賴

implementation 'net.zetetic:android-database-sqlcipher:4.4.3@aar'
implementation "androidx.sqlite:sqlite:2.0.1"

-使用SQLiteCipher提供的相關介面操作

 SQLiteDatabase.loadLibs(this)
                val databaseFile = getDatabasePath("demo.db")
                if (databaseFile.exists()) databaseFile.delete()
                databaseFile.mkdirs()
                databaseFile.delete()
                val database = SQLiteDatabase.openOrCreateDatabase(databaseFile, "test123", null)
                database.execSQL(
                    "CREATE TABLE " + DatabaseHelper.TABLE_MUSIC_TYPE + " (type_id integer primary key autoincrement not null," +
                            "type_no integer,type_name text)"
                )
                database.execSQL(
                    "insert into " + DatabaseHelper.TABLE_MUSIC_TYPE + " (type_no,type_name) " +
                            "values ('" + 1 + "','" + "送餐音樂" + "')"
                )

上面的程式碼在呼叫時,會建立資料庫demo.db,傳入了資料庫密碼,並且建立了一個表music_type,並且向表中插入了一條資料;
注意程式碼中的資料庫相關的操作,都是使用SQLIteCipher中的相關介面即net.sqlcipher.database包名下的相關介面,不要使用成了原生SQLite的相關介面

SQLiteDatabase.loadLibs(this)
                val databaseFile = getDatabasePath("demo.db")
                val database = SQLiteDatabase.openOrCreateDatabase(databaseFile, "test123", null)
                val cursor = database.rawQuery(
                    "select * from " + DatabaseHelper.TABLE_MUSIC_TYPE,
                    null
                )

                var musicTypeList: MutableList<MusicTypeBean> = mutableListOf();

                while (cursor.moveToNext()) {
                    var musicTypeBean = MusicTypeBean();
                    musicTypeBean.id = cursor.getInt(cursor.getColumnIndex("type_no"))
                    musicTypeBean.name = cursor.getString(cursor.getColumnIndex("type_name"))
                    musicTypeList.add(musicTypeBean)
                }
                cursor.close()
                Log.e(TAG, "onClick: " + musicTypeList.size)

上述程式碼就是查詢demo.db資料庫中的music_type表中的資料,獲取資料庫物件的時候,注意傳入的密碼和建立資料庫時要保持一致;

上面使用SQLiteCipher建立資料庫和表,以及向表中插入資料,查詢表中的資料,除了建立資料庫獲取可讀寫資料庫物件和原生SQLite API有些區別一樣,其他執行SQL語句,查詢表中資料的API 和原生 SQlite API是完全一樣的;

SQLiteCipher結合Room框架使用

我們知道在使用SQLite資料庫的時候,我們往往會使用一些比較方便的ORM(物件關係對映)框架來幫助我們運算元據庫,如GreenDAO,Room(Jetpack元件)等,那如何將SQLiteCipher結合這些ORM框架使用;我們這裡介紹一下Google Jetpack元件中的ORM框架 Room結合SQLiteCipher使用;

其實Room結合SQLiteCipher使用,就是在建立資料庫時候,需要先建立一個SupportFactory
,SupportFactory中會傳入通過SQLiteCipher中的SQLiteDatabase獲取的密碼位元組資料

  SQLiteDatabase.loadLibs(this)
                val passphrase = SQLiteDatabase.getBytes("test123".toCharArray())
                val factory = SupportFactory(passphrase, object : SQLiteDatabaseHook {
                    override fun preKey(database: SQLiteDatabase?) {
                        LogUtil.e(TAG, "preKey")
                    }

                    override fun postKey(database: SQLiteDatabase?) {
                        LogUtil.e(TAG, "postKey")
                    }
                }, true)

然後在建立資料庫的時候,通過Room自帶的openHelperFactory()方法傳入建立的SupportFactory即可,這樣就能建立加密資料庫了;其他操作,就按照Room正常的操作即可

var mInstance= Room
                   .databaseBuilder(
                            context.applicationContext,
                            AppDatabase::class.java,
                            DB_NAME
                        ).addCallback(object : RoomDatabase.Callback() {
                            override fun onCreate(db: SupportSQLiteDatabase) {
                                super.onCreate(db)
                                Log.e(TAG, "onCreate: ")
                                initMusicTypeData(context, db)
                            }
                        }).openHelperFactory(factory)
                        .build()

檢視並匯出加密資料庫檔案

-匯出資料庫檔案

我們手機通過USB連線電腦之後,開啟開發者模式,然後在Android Studio選單欄中的View->
Tool Windows->Device File Explorer

然後在Device File Explorer中進入 data/data/應用包名/databases中找到我們建立的資料庫檔案demo.db,然後我們可以右鍵改檔案Save As 匯出該資料庫檔案


-檢視加密資料庫檔案

前面我們已經提到過,可以通過DB Browser for SQLite來檢視加密的資料庫檔案
下載地址:https://sqlitebrowser.org/dl/

下載安裝之後,我們開啟安裝目錄下的DB Browser for SQLCipher.exe程式,然後通過選單欄中的檔案->開啟資料庫->開啟匯出的加密資料庫檔案,然後輸入資料庫檔案的加密密碼,就是我們在程式中SQLiteCipher加密資料庫檔案時使用的密碼,輸入正確密碼後,可以正常開啟資料庫檔案


右鍵表名,選擇瀏覽資料,即可檢視表中的資料

到此這篇關於Android SQLite資料庫加密的操作方法的文章就介紹到這了,更多相關Android SQLite資料庫加密內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com