| 給資料庫加密前面所說的內容網上已經有很多資料,雖然比較零散,但是花點時間也還是可以找到的。現在要說的這個——資料庫加密,資料就很難找。也可能是我操作水平不夠,找不到對應資料。但不管這樣,我還是通過網上能找到的很有限的資料,探索出了給sqlite資料庫加密的完整步驟。6 R: j' I) k8 G1 g* J# h- J , `" a+ o5 x, `6 }* T這裡要提一下,雖然 sqlite 很好用,速度快、體積小巧。但是它儲存的檔案卻是明文的。若不信可以用 NotePad 開啟資料庫檔案瞧瞧,裡面 insert 的內容幾乎一覽無餘。這樣赤裸裸的展現自己,可不是我們的初衷。當然,如果你在嵌入式系統、智能手機上使用 sqlite,最好是不加密,因為這些系統運算能力有限,你做為一個新功能提供者,不能把使用者有限的運算能力全部花掉。7 b" {* B" H9 Q; b. p+ {4 C ( N3 F. Q/ a2 e+ Y0 N$ F9 a Sqlite為了速度而誕生。因此Sqlite本身不對資料庫加密,要知道,如果你選擇標準AES演算法加密,那麼一定有接近50%的時間消耗在加解密演算法 上,甚至更多(效能主要取決於你演算法編寫水平以及你是否能使用cpu提供的底層運算能力,比如MMX或sse系列指令可以大幅度提升運算速度)。* ?$ Q* }( j5 F x v7 ] s" }) z3 N( @Sqlite免費版本是不提供加 密功能的,當然你也可以選擇他們的收費版本,那你得支付2000塊錢,而且是USD。我這裡也不是說支付錢不好,如果只為了資料庫加密就去支付2000 塊,我覺得划不來。因為下面我將要告訴你如何為免費的Sqlite擴充出加密模組——自己動手擴充,這是Sqlite允許,也是它提倡的。 ! F1 g+ I: V! i% C& K5 m3 N' v& ?) D" B& t 那麼,就讓我們一起開始為 sqlite3.c 檔案擴充出加密模組。8 D$ Y7 K) S+ i( ^7 l 3 ~1 G5 Z% h* |0 [0 C) O * r3 G o8 a$ v( h* G 7 T1 M% `% F( R' L7 C8 F i.1 必要的宏0 ]) j, x; k1 E1 `% ~ " ^* h5 ^- e* _; `8 v G 通過閱讀 Sqlite 代碼(當然沒有全部閱讀完,6萬多行代碼,沒有一行是我習慣的風格,我可沒那麼多眼神去看),我搞清楚了兩件事:: L0 V& D: v5 b+ D: \4 }( ` 5 z" k1 j! Y; ~- [9 } Sqlite是支援加密擴充的; # d4 y0 a7 ?% V; I& {; }9 p! W; c; V0 D+ y3 M0 k 需要 #define 一個宏才能使用加密擴充。 ' j2 T4 {$ [" ?7 {. h+ T; j# v- O t+ h' g& E 這個宏就是 SQLITE_HAS_CODEC。: j, m3 [- _6 T7 z+ P 4 W+ J' P0 M* g1 g7 q3 z0 v+ w你在代碼最前面(也可以在 sqlite3.h 檔案第一行)定義: 複製內容到剪貼簿代碼: #ifndef SQLITE_HAS_CODEC #define SQLITE_HAS_CODEC
#endif
如果你在代碼裡定義了此宏,但是還能夠正常編譯,那麼應該是操作沒有成功。因為你應該會被編譯器提示 有一些函數無法連結才對。如果你用的是 VC 2003,你可以在“解決方案”裡右鍵點擊你的工程,然後選“屬性”,找到“C/C++”,再找到“命令列”,在裡面手工添加“/D "SQLITE_HAS_CODEC"”。 ( g4 c' A! V7 g- z) o! o: b' w- u7 N* V$ _6 Y5 N 定義了這個宏,一些被 Sqlite 故意屏蔽掉的代碼就被使用了。這些代碼就是加解密的介面。 & B7 S$ j+ @+ m W6 m $ ~$ ^+ F% G' _- e) a* o- }0 G嘗試編譯,vc會提示你有一些函數無法連結,因為找不到他們的實現。0 o$ H5 ~) [8 i7 C, q& M" ~% F , I m, s. `7 o2 M+ \- o. @5 G; V如果你也用的是VC2003,那麼會得到下面的提示: 複製內容到剪貼簿代碼: error LNK2019: 無法解析的外部符號 _sqlite3CodecGetKey ,該符號在函數 _attachFunc 中被引用 error LNK2019: 無法解析的外部符號 _sqlite3CodecAttach ,該符號在函數 _attachFunc 中被引用
error LNK2019: 無法解析的外部符號 _sqlite3_activate_see ,該符號在函數 _sqlite3Pragma 中被引用
error LNK2019: 無法解析的外部符號 _sqlite3_key ,該符號在函數 _sqlite3Pragma 中被引用
fatal error LNK1120: 4 個無法解析的外部命令
這是正常的,因為Sqlite只留了介面而已,並沒有給出實現。% h) b& _. C$ m8 n; k& e* j, Q ) q3 R* m. A8 F+ G# ]! [ 下面就讓我來實現這些介面。 |