隨着移動互聯網的發展,手機使用愈來愈普遍,sqlite做爲手機端存儲的一種解決方案,使用也很是廣泛。可是sqlite自己安全特性卻比較弱,好比不支持用戶權限,只要能獲取到數據庫文件就能進行訪問;另外也沒有加密功能,任何人獲取到文件後,就能夠查到明文數據。這使得你們對於sqlite又愛又不敢用,畢竟用戶的隱私是很是重要的。Sqlite分爲開源版本和收費版,收費的版本是支持加密的,只不過須要付2000刀的技術支持費。固然,因爲sqlite自己是開源的,業內有不少產品對sqlite增長了加密功能,好比wxsqlite,sqlcipher等。所以想無償使用加密版本的sqlite也不是不能夠,但前提是使用過程遇到問題,必定要能hold住,由於免費的東西不必定是穩定的。廢話少說,本文主要討論兩個問題, 1.本身如何實現sqlite的加密功能,2.如何使用加密的sqlite。算法
加密算法選擇sql
要實現加密,首先須要選擇一種主流、高效、安全的加密算法,對於手機端和嵌入式設備,還要加上一條簡單的原則。加密算法主要分爲對稱加密算法和非對稱加密算法,對於文本加密通常採用對稱加密,而對於祕鑰的管理則採用非對稱加密。目前主流的對稱加密算法有DES,AES,RC系列,TEA系列, Blowfish等,非對稱加密算法有RSA、Diffie-Hellman等。本人對幾種常見的對稱加密算法進行了測試,綜合起來AES和XXTEA算法性能最好,XXTEA的優點在於實現很是簡單,代碼不到100行,在端設備上也是一種優點。另外,騰訊一直在使用TEA系列算法做爲它的通信加密和本地存儲加密,用實踐證實了TEA系列算法的可靠性和安全性。下圖是AES算法和XXTEA算法的一些測試數據,僅供參考。XXTEA-256和XXTEA-64,分別表示塊大小是256個INT和64個INT。經過測試讀寫200M數據的時間來評估算法的優劣,每一個數據經過測試5次取平均值。數據庫
|
不加密緩存 |
AES安全 |
XXTEA-256框架 |
XXTEA-64函數 |
寫操做性能 |
7879.3ms測試 |
10283.6ms加密 |
10577.3ms |
10649.4ms |
讀操做 |
315.69ms |
3681.4ms |
3527ms |
3598ms |
上層應用加密
選擇好加密算法,那麼要實現加密功能了。有童鞋會問,爲啥必定要在sqlite內部實現加密,上層應用加密不是同樣OK嗎?這個確實能夠。不少開發語言都自帶了加密庫函數,直接調用便可。寫入數據時進行加密,讀出數據時再進行解密。但這種方式主要有如下幾個缺點:
因此,總地來講,應用層是一種解決方案,但對開發者不太友好。
sqlite自身加密
從原理上來看,加入加密模塊功能也相對簡單,在寫入數據塊前,調用加密模塊進行數據塊加密,而後寫入文件;而在讀取數據塊時,先調用加密模塊解密,而後加載到緩存。加密模塊(紅色標註)在整個sqlite實現框架的位置以下圖。
實現層面,咱們要作的工做主要包括三部分,實現加密算法,而後將加密接口與sqlite關聯起來,最後在合適的位置(讀寫文件),調用加/解密接口完成加密解密工做。因爲sqlite自身已經預留了加解密接口,所以第3部分的工做已經幫咱們作了,咱們只須要實現第1和第2部分工做。核心接口以下:
1.sqlite3CodecAttach
含義:調用sqlite3PagerSetCodec 將加密接口與sqlite的pager模塊關聯
2.xxxCodec
含義:本身定義的加密接口,輸入參數是(page_no,讀寫模式),將指定page加、解密。
3.sqlite3_key
含義:設置數據庫密鑰,sqlite3_open後調用該接口。對於非加密庫,若調用該接口,會致使後續訪問數據報錯。
Error: file is encrypted or is not a database
4.sqlite3_rekey
含義:修改數據庫密鑰,這個接口會遍歷數據庫中的全部頁,而後用新密鑰對頁進行加密,寫入文件。若將新密鑰設置爲NULL,則能夠將加密庫變爲普通庫。
5.sqlite3_activate_see
sqlite3CodecGetKey
這兩個接口沒有實際做用,能夠實現一個空函數,保證能編譯經過就行。
加密sqlite使用
若是順利,咱們如今已經有了一個包含加密功能的sqlite了,那麼如何使用?下面主要列了一些常見的場景。
1.如何判斷一個db文件是否加密
$sqlite3 ./data/test.db
sqlite> .tables Error: file is encrypted or is not a database
sqlite> pragma key='123456' ;
sqlite> .tables
Error: file is encrypted or is not a database
對於加密的db文件,若是沒有執行pragma key=xxx命令直接執行,則會報錯。假設密碼是 123456,報錯後,從新執行pragma key命令,而後執行.tables,這時候依舊報錯。這個主要是由於密鑰在鏈接建立時初始化,因此對於加密數據庫,須要執行的第一條命令是pragma key=xxx
2.導出加密文件數據
$sqlite3 ./data/test.db // 打開加密數據庫文件test.db
sqlite> pragma key='123456'; // 設置祕鑰
sqlite> .output aaa.sql //將輸出重定向到文件aaa.sql
sqlite> .dump //導出數據庫
sqlite> .exit 這樣aaa.sql中包含了test.db中數據庫的明文內容。
3.解密加密數據庫
$sqlite3 ./data/test.db
sqlite> pragma key='123456'
sqlite> pragma rekey=''; //設置密鑰爲空,則將密文數據庫解密。
//解密後能夠直接打開數據庫
$sqlite3 ./data/test.db
sqlite> .tables
sqlite> .exit
參考文檔