說到數據庫加密,目前最好且唯一的方案就是SqlCipher對sqlite3整體加密,微信也用的它。開源,且支持很多平台。
單就Android來說,集成不算太麻煩,1個jar包,3個so庫,1個zip。
jar包中基本上重寫了android.database.sqlite包中所有的類,全部替換成了net.sqlcipher.sqlite包。why?因為sqlcipher加密后,需要密碼才能打開該數據庫。所以它把所有的都重寫了一遍,這是一個坑,一會Stay再來說明。
整體來說sqlcipher還是比較好用的,封裝好了跟正常操作數據庫的方式一樣,只是在getWritableDatabase()時要多傳個password參數。
sqlcipher在性能上沒有太大的損失,而且在移動端數據量不是很大,基本可以忽略不計了。
現在坑來了,假如你之前用的是數據庫框架,而不是使用原生的方式,那么集成起來還有些麻煩。當然如果用的對象型數據庫,那跟sqlcipher就一點關系都沒有了。我們這里只說,如果以前用的是基於sqlite的數據庫框架集成sqlcipher。
比如,ormlite,它是object-relation-mapping,將你model中聲明的變量通過注解的方式和數據庫的表字段一一對應起來。
這個映射不在乎數據庫是sqlite,mysql還是什么。在ormlite-core核心包中,與數據庫的連接是個proxy,在對應的ormlite-android中來使用android系統提供給我們的db連接方式來實現這個proxy。這就是為什么ormlite要有兩個jar包。
如果要使用sqlcipher,那么所有android.database.sqlite中的類都要換成net.sqlcipher.sqlite中的類。但是ormlite-android中用的都是android.database.sqlite。這是個問題。對吧?
所幸ormlite分成了兩個包,ormlite-core.jar, ormlite-android.jar 並且它們還是開源的。我們可以把ormlite-android.jar中所有引用android.database.sqlite的地方手動替換為net.sqlcipher.sqlite。這個注意不錯吧?
也就是說。ormlite-core.jar不變,照樣導入這個jar,只是ormlite-android.jar要改成sqlcipher.jar中的那些Cursor, SqliteDatabase等等。
確定好解決方案之后,剩下的就好辦了。
這里說android studio的集成方式,如果是eclipse可以直接新建一個工程,做成library。
首先,新建一個module,因為會改很多東西,所以盡量單獨放一個module,以后做其他項目可以方便遷移。
導入sqlcipher,配置好環境。確保sqlcipher沒問題,能正確的加解密,進行crud。
導入ormlite-core.jar, 建議使用android studio的jcenter倉庫來導入
去ormlite的github主頁,把ormlite-android的源代碼拉下來,只需要ormlite-android就可以了。
注意。要用git拉代碼,別download as zip。你需要手動切換到對應的commit上。比如ormlite-core.jar版本是4.48,那么對應的ormlite-android也應該切換到4.48的tag上。保證兩個版本一致。
將所有ormlite-android中的代碼copy到你的module/src目錄下,然后手動將所有import android.database.sqlite的地方手動替換為import net.sqlcipher.sqlite
改為之后會有一個錯誤,因為sqlcipher需要密碼去getWritableDatabase(String password),這里需要對源碼做些修改,如下圖。
當然還有其他的小錯誤,自己想辦法解決好了,不難。
在自己的主app module中要繼承的SqliteOpenHelper還是OrmliteSqliteOpenHelper,sqlcipher已經集成到ormlite內部了,對外不可見。你只需要用帶有password的構造方法就可以了。如下圖。
其他調用方式都不用變了。以前寫的ormlite代碼都不用換了。開森,對不對。
代碼已經放到github上了。
github.com/Stay/ormlite-sqlcipher
p.s. 如果你現在使用的ormlite版本不是4.48,那么就自己動手把對應的ormlite-android的源代碼拉下來手動替換。