SQLite
3
开源版本不带加密功能,如果内部保存的是敏感信息,比如帐号密码等信息那安全性就会大打折扣。我们的目的就是给数据库添加最后一层防护,即使别人得到数据库文件也无法或很难拿到敏感信息。
总的来说有两种方法,一个是对数据库字段加密,另一个是对 SQLite
进行扩展,使用作者预留了加密解密的相关接口。这两个方法各有优劣,可以根据适用场景自行选择。
我们先说第二种方法,这里介绍一个开源项目:,该项目是一个
SQLite 的 C++ warpper,它顺带将 SQLite 的加密函数实现了,并且它使用 AES 算法进行加密。你可以在下
载到最新的包,在目录
\sqlite3\secure 下你可以找到一个 加密扩展的源 文件,而且
wxSQLite3
项目更新很快,你总是可以下载到较新的包。
sqlite的版本是 sqlite-source-3_5_9.zip ,的版本是wxsqlite3-1.9.2.tar.gz
将这两个文件解压缩后,将wxsqlite3-1.9.2/sqlite3/secure/src/下的codec目录copy到解压后的sqlite-source目录下,然后编写Makefile,将所有的源文件编译成一个so库:
COMPILE=g++ -c -fPIC -g -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_HAS_CODEC -o "$(OUTDIR)/$(*F).o" $(CFG_INC) $<
LINK=g++ -g -shared -W1 -o $(OUTFILE) $(ALL_OBJ)
编译时需要指定-DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_HAS_CODEC宏。
执行#make,之后就会在sqlite/目录下看到libsqlite.so。
源代码和Makefile:sqlite-src.rar
然后编写测试代码,首先需要创建数据库,并给数据库添加密码,关键代码如下:
-
sqlite3 *db;
-
sqlite3_stmt *stat;
-
char *zErrMsg = 0;
-
-
sqlite3_open(FileRoot, &db);
-
if(db == NULL)
-
{
-
return -1;
-
}
-
-
sqlite3_rekey(db,argv[2],strlen(argv[2]));
-
-
sqlite3_close(db);
之后测试数据库操作,关键代码如下:
-
db = NULL;
-
int rt = sqlite3_open(argv[1],&db);
-
……
-
sqlite3_key(db,argv[2],strlen(argv[2]));
-
rt = sqlite3_prepare(db, "insert into list values (?,?);", -1, &stat, 0);
-
……
-
rt = sqlite3_bind_int(stat , 1 , inum);
-
……
-
rt = sqlite3_bind_text(stat, 2, (const char*)key, 1024 , NULL);
-
……
-
rt = sqlite3_step(stat);
-
-
rt = sqlite3_finalize(stat);
-
-
sqlite3_close(db);
现在说一下第一种方法:
对字段加密使用起来比较简单,我们不需要对sqlite进行修改就可以使用,当然这个方法有他的使用范围,不如,如果我们需要存储用户名密码对,就可以只对密码进行加密,然后存储到数据库里面。
关键代码如下:
-
int rt = sqlite3_open(argv[1],&db);
-
-
rt = sqlite3_prepare(db, "insert into list values (?,?);", -1, &stat, 0);
-
……
-
rt = sqlite3_bind_int(stat , 1 , inum);
-
……
-
int outlen = 0;
-
unsigned char* endata = cp.bf_encrypt((unsigned char*)key,1024,outlen);
-
-
rt = sqlite3_bind_text(stat, 2, (const char*)key, 1024 , NULL);
-
delete endata;
-
……
-
-
rt = sqlite3_step(stat);
-
int ncols = sqlite3_column_count(stat);
-
……
-
-
rt = sqlite3_finalize(stat);
-
……
-
sqlite3_close(db);
cp是加密类cipher的对象,负责加密字段。
测试代码:
sqlite-src.rar
通过测试发现,第一种方法的速度比较均匀,不会随数据库文件的变化而变化,第二种方法(sqlite扩展)当数据库增大时对数据库操作的速度会下降,数据库文件越大下降越明显。
阅读(1656) | 评论(0) | 转发(0) |