近来在学习CodeBlocks和wxWidgets,网上有人说要操纵sqlite3使用wxSqlite比较好,实现了加密,于是我就按照他们的方法一步步实现,在编译wxSqlite和sqlite3的过程中虽说出现一些小插曲,但总算是都编译通过了,最让我头大的是用wxSqlite操纵sqlite3时出现一堆错误,痛苦一天之后决定放弃了(谁可以指导一下,感激不尽),还是转到我比较熟悉的CppSQLite3。但是我发现新版的CppSQLite3.2没有提供加密接口,于是我就想到将以前版本的接口函数移植到新版中来,试了一下,还可以,在此写几笔,以备查询。
一、静态编译带加密的sqlite3
1、下载sqlite-amalgamation-3071300(下载地址:http://www.sqlite.org/download.html)
2、打开CodeBlocks,新建Static library,项目标题为Sqlite3Encrypt,其他默认即可。
3、解压sqlite-amalgamation-3071300到某个位置,并将文件夹内所有的文件拷贝到Sqlite3Encrypt工程目录里。
4、下载wxsqlite3(下载地址:http://wxcode.sourceforge.net/components/wxsqlite3/),解压(我解压的位置为G:\wxSqlite3),并将G:\wxSqlite3\wxsqlite3-3.0.0\sqlite3\secure\src内的codec.c,codec.h,rijndael.c,rijndael.h,codecext.c和sqlite3secure.c拷贝到Sqlite3Encrypt工程目录里面,在Sqlite3Encrypt工程里添加sqlite3secure.c文件。
5、添加预处理:
在Sqlite3Encrypt上点击右键-属性,弹出对话框,配置如图:
SQLITE_HAS_CODEC=1
CODEC_TYPE=CODEC_TYPE_AES128
SQLITE_CORE
THREADSAFE
SQLITE_SECURE_DELETE
SQLITE_SOUNDEX
SQLITE_ENABLE_COLUMN_METADATA
点击确定退出设置。
6、编译Sqlite3Encrypt,不出意外的话,就会生成libSqlite3Encrypt.a,即为带加密的sqlite静态库。编译过程中如果出现error: too few arguments to function 'sqlite3BtreeRollback'的错误,就将sqlite3BtreeRollback(pbt)更改为sqlite3BtreeRollback(pbt,SQLITE_OK)并保存、重新编译,即会消除错误。
二、为CppSQLite3.2添加加密接口(CppSQLite3.2下载地址:
http://www.codeproject.com/Articles/6343/CppSQLite-C-Wrapper-for-SQLite)
1、在CppSQLite3.h的CppSQLite3DB类中添加如下函数声明:
class CppSQLite3DB
{
public:
CppSQLite3DB();
virtual ~CppSQLite3DB();
void open(const char* szFile);
void open(const char* szFile, const char* szPass);
void rekey(const char* szPass);
void close();
………………………………
2、在CppSQLite3.cpp中添加上述函数的实现:
………………………………
void CppSQLite3DB::open(const char* szFile)
{
int nRet = sqlite3_open(szFile, &mpDB);
if (nRet != SQLITE_OK)
{
const char* szError = sqlite3_errmsg(mpDB);
throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
}
setBusyTimeout(mnBusyTimeoutMs);
}
void CppSQLite3DB::open(const char* szFile,const char* szPass)
{
int nRet = sqlite3_open(szFile, &mpDB);
if (nRet != SQLITE_OK)
{
const char* szError = sqlite3_errmsg(mpDB);
throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
}
if(szPass != NULL)
{
int nRet = sqlite3_key(mpDB, szPass, strlen(szPass));
if (nRet != SQLITE_OK)
{
const char* szError = sqlite3_errmsg(mpDB);
throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
}
}
setBusyTimeout(mnBusyTimeoutMs);
}
void CppSQLite3DB::rekey(const char* szPass)
{
if(szPass != NULL)
{
int nRet = sqlite3_rekey(mpDB, szPass, strlen(szPass));
if (nRet != SQLITE_OK)
{
const char* szError = sqlite3_errmsg(mpDB);
throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
}
}
setBusyTimeout(mnBusyTimeoutMs);
}
………………………………
三、用CppSQLite3.2操纵libSqlite3Encrypt
在下载CppSQLite3.2时,里面有CppSQLite3.2的使用实例,如:CppSQLiteDemo。
打开数据库可以用:
db.open("数据库路径+名称"); //不带加密方式打开数据库
db.open("数据库路径+名称","密码"); //带加密的方式打开
修改密码可以用:
db.rekey("密码"); //修改密码
参考:http://topic.csdn.net/u/20111030/13/e794f504-5d6a-4b5e-86e0-20977349814b.html