免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2446 | 回复: 0
打印 上一主题 下一主题

SQLite 数据库加密的一种解决方案 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-23 20:47 |只看该作者 |倒序浏览
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);


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/76292/showart_2058694.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP