https://github.com/utelle/wxsqlite3 提供了加密版的 sqlite,支持 premake5 編譯证鸥。
SQLite3 的加密函數(shù)說明
sqlite3_key
是輸入密鑰僚楞,如果數(shù)據(jù)庫已加密必須先執(zhí)行此函數(shù)并輸入正確密鑰才能進(jìn)行操作,如果數(shù)據(jù)庫沒有加密枉层,執(zhí)行此函數(shù)后進(jìn)行數(shù)據(jù)庫操作反而會出現(xiàn) “此數(shù)據(jù)庫已加密或不是一個數(shù)據(jù)庫文件” 的錯誤泉褐。
int sqlite3_key(sqlite3 *db, const void *pKey, int nKey)
,db 是指定數(shù)據(jù)庫鸟蜡,pKey 是密鑰膜赃,nKey 是密鑰長度。例:sqlite3_key( db, "abc", 3);
sqlite3_rekey
是變更密鑰或給沒有加密的數(shù)據(jù)庫添加密鑰或清空密鑰矩欠,變更密鑰或清空密鑰前必須先正確執(zhí)行 sqlite3_key
财剖。在正確執(zhí)行 sqlite3_rekey
之后在 sqlite3_close
關(guān)閉數(shù)據(jù)庫之前可以正常操作數(shù)據(jù)庫悠夯,不需要再執(zhí)行 sqlite3_key
。
int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey)
躺坟,參數(shù)同上沦补。
清空密鑰為 sqlite3_rekey(db, NULL, 0)
。
其實 SQLite 的兩個加密函數(shù)使用起來非常的簡單咪橙,下面分情況說明:
- 給一個未加密的數(shù)據(jù)庫添加密碼:如果想要添加密碼夕膀,則可以在打開數(shù)據(jù)庫文件之后,關(guān)閉數(shù)據(jù)庫文件之前的任何時刻調(diào)用 sqlite3_key 函數(shù)即可美侦,該函數(shù)有三個參數(shù)产舞,其中第一個參數(shù)為數(shù)據(jù)庫對象,第二個參數(shù)是要設(shè)定的密碼菠剩,第三個是密碼的長度易猫。例如:
sqlite3_key(db,"1q2w3e4r",8); // 給數(shù)據(jù)庫設(shè)定密碼 1q2w3e4r
注:如果數(shù)據(jù)庫沒有加密,執(zhí)行此函數(shù)后進(jìn)行數(shù)據(jù)庫操作反而會出現(xiàn) “此數(shù)據(jù)庫已加密或不是一個數(shù)據(jù)庫文件” 的錯誤具壮?經(jīng)測試准颓,只能在新建數(shù)據(jù)庫時設(shè)置密碼!
讀取一個加密數(shù)據(jù)庫中的數(shù)據(jù):完成這個任務(wù)依然十分簡單棺妓,你只需要在打開數(shù)據(jù)庫之后攘已,再次調(diào)用一下 sqlite3_key 函數(shù)即可,例如怜跑,但數(shù)據(jù)庫密碼是 123456 時样勃,你只需要在代碼中加入
sqlite3_key(db,"123456",6);
更改數(shù)據(jù)庫密碼:首先你需要使用當(dāng)前的密碼正確的打開數(shù)據(jù)庫,之后你可以調(diào)用
sqlite3_rekey(db,"112233",6)
來更改數(shù)據(jù)庫密碼性芬。刪除密碼:也就是把數(shù)據(jù)庫恢復(fù)到明文狀態(tài)破加。這時你仍然只需要調(diào)用
sqlite3_rekey
函數(shù)揪利,并且把該函數(shù)的第二個參數(shù)置為 NULL 或者 "", 或者把第三個參數(shù)設(shè)為 0直砂。
SQLite 添加了加密解密功能后供璧,使用方法如下:
在調(diào)用 sqlite3_open() 函數(shù)打開數(shù)據(jù)庫后,要調(diào)用 sqlite3_key() 函數(shù)為數(shù)據(jù)庫設(shè)置密碼汽煮;
如果數(shù)據(jù)庫之前有密碼搏熄,則調(diào)用 sqlite3_key() 函數(shù)設(shè)置正確密碼才能正常工作;
如果一個數(shù)據(jù)庫之前沒有密碼暇赤,且已經(jīng)有數(shù)據(jù)心例,則不能再為其設(shè)置密碼;
如果要修改密碼鞋囊,則需要在第一步操作后止后,調(diào)用 sqlite3_rekey() 函數(shù)設(shè)置新的密碼;
設(shè)置了密碼的 SQLite 數(shù)據(jù)庫,無法使用第三方工具打開译株;
只不過這個加密是用的自帶的 sqlite3.dll 里的函數(shù)乘寒,我們呢,只要把. wxsqlite3 文件夾下 sqlite3\secure\aes128\dll\release 里的 sqlite3.dll 替換掉 SQLite Developer 的 sqlite3.dll, 然后你可以直接用 SQLite Developer 對 數(shù)據(jù)庫文件加密了匪补,并且程序里伞辛,只要 sqlite3_key() 后也可以正常讀取數(shù)據(jù),艾瑪夯缺,太美好了蚤氏。
使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i;
for (i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
static char* passwd = "helloworld";
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
/* Open database */
rc = sqlite3_open("test.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
} else {
fprintf(stdout, "Opened database successfully\n");
}
rc = sqlite3_key(db, passwd, strlen(passwd));
if (rc) {
fprintf(stderr, "Can't encrypt database: %s\n", sqlite3_errmsg(db));
exit(0);
} else {
fprintf(stdout, "Encrypt database successfully\n");
}
/* Create SQL statement */
sql = "CREATE TABLE IF NOT EXISTS COMPANY (" \
"ID INT PRIMARY KEY NOT NULL," \
"NAME TEXT NOT NULL," \
"AGE INT NOT NULL," \
"ADDRESS CHAR(50)," \
"SALARY REAL );"; //Create table
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Table created successfully\n");
}
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
"VALUES (1, 'Paul', 32, 'California', 20000.00); " \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
"VALUES (2, 'Allen', 25, 'Texas', 15000.00); " \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00);" \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
"VALUES (4, 'Mark', 25, 'Rich-Mond', 65000.00);"; //Insert data
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Records created successfully\n");
}
/* Create SQL statement */
sql = "SELECT * from COMPANY"; //Select data
/* Execute SQL statement */
const char* data = "Callback function called";
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
return 0;
}
CppSQLite3 是對 sqlite3 的一個 C++ 封裝。
CppSQLite3U is a C++ unicode wrapper around the SQLite database柱告。
http://softvoile.com/development/CppSQLite3U/