Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1237364
  • 博文数量: 389
  • 博客积分: 2874
  • 博客等级: 少校
  • 技术积分: 3577
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 10:34
文章分类

全部博文(389)

文章存档

2020年(2)

2018年(39)

2017年(27)

2016年(3)

2015年(55)

2014年(92)

2013年(54)

2012年(53)

2011年(64)

分类: SQLite/嵌入式数据库

2013-05-13 10:06:55

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
然后编写测试代码,首先需要创建数据库,并给数据库添加密码,关键代码如下:

点击(此处)折叠或打开

  1. sqlite3 *db;
  2.     sqlite3_stmt *stat;
  3.     char *zErrMsg = 0;

  4.     sqlite3_open(FileRoot, &db);
  5.     if(db == NULL)
  6.     {
  7.         return -1;
  8.     }

  9.     sqlite3_rekey(db,argv[2],strlen(argv[2]));

  10.     sqlite3_close(db);

之后测试数据库操作,关键代码如下:

点击(此处)折叠或打开

  1. db = NULL;
  2. int rt = sqlite3_open(argv[1],&db);
  3. ……
  4. sqlite3_key(db,argv[2],strlen(argv[2]));
  5. rt = sqlite3_prepare(db, "insert into list values (?,?);", -1, &stat, 0);
  6. ……
  7. rt = sqlite3_bind_int(stat , 1 , inum);
  8. ……
  9. rt = sqlite3_bind_text(stat, 2, (const char*)key, 1024 , NULL);
  10. ……
  11. rt = sqlite3_step(stat);

  12. rt = sqlite3_finalize(stat);

  13. sqlite3_close(db);
现在说一下第一种方法:
对字段加密使用起来比较简单,我们不需要对sqlite进行修改就可以使用,当然这个方法有他的使用范围,不如,如果我们需要存储用户名密码对,就可以只对密码进行加密,然后存储到数据库里面。
关键代码如下:

点击(此处)折叠或打开

  1. int rt = sqlite3_open(argv[1],&db);

  2. rt = sqlite3_prepare(db, "insert into list values (?,?);", -1, &stat, 0);
  3. ……
  4. rt = sqlite3_bind_int(stat , 1 , inum);
  5. ……
  6. int outlen = 0;
  7. unsigned char* endata = cp.bf_encrypt((unsigned char*)key,1024,outlen);

  8. rt = sqlite3_bind_text(stat, 2, (const char*)key, 1024 , NULL);
  9. delete endata;
  10. ……

  11. rt = sqlite3_step(stat);
  12. int ncols = sqlite3_column_count(stat);
  13. ……

  14. rt = sqlite3_finalize(stat);
  15. ……
  16. sqlite3_close(db);
cp是加密类cipher的对象,负责加密字段。
测试代码:sqlite-src.rar
通过测试发现,第一种方法的速度比较均匀,不会随数据库文件的变化而变化,第二种方法(sqlite扩展)当数据库增大时对数据库操作的速度会下降,数据库文件越大下降越明显。







阅读(1587) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~