SQLite是一個非常小巧的跨平臺嵌入式數據庫,它的數據庫以文件的形式存放在本地磁盤上,但是在其開源的免費版中它卻缺少了一個數據庫中幾乎是必備的功能,那就是對于數據庫的加密。SQLite的數據庫文件可以被任何的文本編輯工具打開,從而獲取到其中的數據,這一點令很多開發者感到不安。
但是其實SQLite是支持數據庫加密的,前些天看到了網友arris的帖子,具體如下:
sqlite的源代碼中原本就考慮了加密的實現,并且保留了接口sqlite3_key和sqlite3_rekey,只是這兩個函數在free版本中沒有實現,但幸運的是,sqlite的源代碼的代碼是開放并允許修改,我們可以很方便的增加加密的實現。在http://www.sqlite.com.cn/POParticle/3/216.Html鏈接的的代碼包中就包含有可加密sqlite的源代碼的實現,我根據這個包編譯了一個可加密的sqlite。這個包加密實現調用了windows API 的加密函數,所以只能在windows中使用。
這個可加密的版本是在一個ADO.NET 2.0 SQLite Data Provider的基礎上改過來的(http://www.sqlite.com.cn/POParticle/3/216.Html),據原作者聲稱效率損失在千分之一以下。原始工程是基于VS2005的,但是考慮到其普及性還不是很廣,所以重新建立了一個居于VC2003的工程。
其實SQLite的兩個加密函數使用起來非常的簡單,下面分情況說明:
① 給一個未加密的數據庫添加密碼:如果想要添加密碼,則可以在打開數據庫文件之后,關閉數據庫文件之前的任何時刻調用sqlite3_key函數即可,該函數有三個參數,其中第一個參數為數據庫對象,第二個參數是要設定的密碼,第三個是密碼的長度。例如:sqlite3_key(db,"1q2w3e4r",8); //給數據庫設定密碼1q2w3e4r
② 讀取一個加密數據庫中的數據:完成這個任務依然十分簡單,你只需要在打開數據庫之后,再次調用一下sqlite3_key函數即可,例如,但數據庫密碼是123456時,你只需要在代碼中加入sqlite3_key(db,"123456",6);
① 更改數據庫密碼:首先你需要使用當前的密碼正確的打開數據庫,之后你可以調用sqlite3_rekey(db,"112233",6) 來更改數據庫密碼。
② 刪除密碼:也就是把數據庫恢復到明文狀態。這時你仍然只需要調用sqlite3_rekey函數,并且把該函數的第二個參數置為NULL或者"",或者把第三個參數設為0。
加密后數據庫文件顯示為亂碼:
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, "測試數據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);
具體的源代碼如下:
SQLite
SQLite
例子1,例子2
新聞熱點
疑難解答