
但是其實(shí)SQLite是支持?jǐn)?shù)據(jù)庫(kù)加密的,前些天看到了網(wǎng)友arris的帖子,具體如下:
sqlite的源代碼中原本就考慮了加密的實(shí)現(xiàn),并且保留了接口sqlite3_key和sqlite3_rekey,只是這兩個(gè)函數(shù)在free版本中沒(méi)有實(shí)現(xiàn),但幸運(yùn)的是,sqlite的源代碼的代碼是開(kāi)放并允許修改,我們可以很方便的增加加密的實(shí)現(xiàn)。在http://www.sqlite.com.cn/POParticle/3/216.Html鏈接的的代碼包中就包含有可加密sqlite的源代碼的實(shí)現(xiàn),我根據(jù)這個(gè)包編譯了一個(gè)可加密的sqlite。這個(gè)包加密實(shí)現(xiàn)調(diào)用了windows API 的加密函數(shù),所以只能在windows中使用。
這個(gè)可加密的版本是在一個(gè)ADO.NET 2.0 SQLite Data Provider的基礎(chǔ)上改過(guò)來(lái)的(http://www.sqlite.com.cn/POParticle/3/216.Html),據(jù)原作者聲稱(chēng)效率損失在千分之一以下。原始工程是基于VS2005的,但是考慮到其普及性還不是很廣,所以重新建立了一個(gè)居于VC2003的工程。
其實(shí)SQLite的兩個(gè)加密函數(shù)使用起來(lái)非常的簡(jiǎn)單,下面分情況說(shuō)明:
① 給一個(gè)未加密的數(shù)據(jù)庫(kù)添加密碼:如果想要添加密碼,則可以在打開(kāi)數(shù)據(jù)庫(kù)文件之后,關(guān)閉數(shù)據(jù)庫(kù)文件之前的任何時(shí)刻調(diào)用sqlite3_key函數(shù)即可,該函數(shù)有三個(gè)參數(shù),其中第一個(gè)參數(shù)為數(shù)據(jù)庫(kù)對(duì)象,第二個(gè)參數(shù)是要設(shè)定的密碼,第三個(gè)是密碼的長(zhǎng)度。例如:sqlite3_key(db,"1q2w3e4r",8); //給數(shù)據(jù)庫(kù)設(shè)定密碼1q2w3e4r
② 讀取一個(gè)加密數(shù)據(jù)庫(kù)中的數(shù)據(jù):完成這個(gè)任務(wù)依然十分簡(jiǎn)單,你只需要在打開(kāi)數(shù)據(jù)庫(kù)之后,再次調(diào)用一下sqlite3_key函數(shù)即可,例如,但數(shù)據(jù)庫(kù)密碼是123456時(shí),你只需要在代碼中加入sqlite3_key(db,"123456",6);
① 更改數(shù)據(jù)庫(kù)密碼:首先你需要使用當(dāng)前的密碼正確的打開(kāi)數(shù)據(jù)庫(kù),之后你可以調(diào)用sqlite3_rekey(db,"112233",6) 來(lái)更改數(shù)據(jù)庫(kù)密碼。
② 刪除密碼:也就是把數(shù)據(jù)庫(kù)恢復(fù)到明文狀態(tài)。這時(shí)你仍然只需要調(diào)用sqlite3_rekey函數(shù),并且把該函數(shù)的第二個(gè)參數(shù)置為NULL或者"",或者把第三個(gè)參數(shù)設(shè)為0。
加密后數(shù)據(jù)庫(kù)文件顯示為亂碼:

為此我建立了一個(gè)簡(jiǎn)單的示例:
sqlite3 *db;
sqlite3_stmt *stat;
char *zErrMsg = 0;
char temp[256], FileRoot[256];
char buffer2[1024]="0";
sprintf(temp, _T("%s"), _T("utf.db"));
CCodingConv::GB2312_2_UTF8(FileRoot, 256, temp, 0);
sqlite3_open(FileRoot, &db);
if(db == NULL)
{
return -1;
}
sqlite3_key(db,"1q2w3e4r",8);
sqlite3_exec(db, "CREATE TABLE list (fliename varchar(128) UNIQUE, fzip text);", 0, 0, &zErrMsg);
sqlite3_prepare(db, "insert into list values ('中文GB2312編碼',?);", -1, &stat, 0);
strcpy(temp, "測(cè)試數(shù)據(jù)UTF-8的支持情況");
int len = (int)strlen(temp);
sqlite3_bind_text(stat, 1, temp, len, NULL);
sqlite3_step(stat);
sqlite3_prepare(db, "select * from list;", -1, &stat, 0);
sqlite3_step(stat);
const unsigned char * test = sqlite3_column_text(stat, 1);
int size = sqlite3_column_bytes(stat, 1);
printf("%s", test);
sqlite3_finalize(stat);
//sqlite3_rekey(db,"",0);
sqlite3_close(db);
具體的源代碼如下:


