【数据库】SQLITE3 加密3

上面写了两个扩展函数,如何把扩展函数跟 Sqlite 挂接起来,这个过程说起来比较麻烦。我直接贴代码。
/ I" l   _$ K6 }( V+ N7 G# ~
% Z# ^7 P; H" U% u分3个步骤。
8 ?2 |3 V; D7 r! H, n9 W+ A7 R6 j; G; s   o" }8 g2 Y' x" o
首先,在 sqlite3.c 文件顶部,添加下面内容:
复制内容到剪贴板
代码:
#ifdef SQLITE_HAS_CODEC

#include "./crypt.h"

/***********

用于在 sqlite3 最后关闭时释放一些内存

***********/

void sqlite3pager_free_codecarg(void *pArg);

#endif
这个函数之所以要在 sqlite3.c 开头声明,是因为下面在 sqlite3.c 里面某些函数里要插入这个函数调用。所以要提前声明。5 [9 e- u/ a& C- b3 X3 g; I

1 V1 D/ m- J   U8 Z ( ]* [5 j# @/ w2 a, v
. B! C   z; a5 _9 O3 a
其次,在sqlite3.c文件里搜索“sqlite3PagerClose”函数,要找到它的实现代码(而不是声明代码)。3 z( e( m   L4 r; t& \

9 G2 [# n% w" }* R实现代码里一开始是:
复制内容到剪贴板
代码:
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT

   /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to

   ** malloc() must have already been made by this thread before it gets

   ** to this point. This means the ThreadData must have been allocated already

   ** so that ThreadData.nAlloc can be set.

   */

   ThreadData *pTsd = sqlite3ThreadData();

   assert( pPager );

   assert( pTsd && pTsd->nAlloc );

#endif

需要在这部分后面紧接着插入:
复制内容到剪贴板
代码:
#ifdef SQLITE_HAS_CODEC

   sqlite3pager_free_codecarg(pPager->pCodecArg);

#endif
这里要注意,sqlite3PagerClose 函数大概也是 3.3.17版本左右才改名的,以前版本里是叫 “sqlite3pager_close”。因此你在老版本sqlite代码里搜索“sqlite3PagerClose”是搜不到的。# U& Z' b" z) Y; j# i

( F5 H0 V1 L( V; J; t7 p类似的还有 “sqlite3pager_get”、“sqlite3pager_unref”、“sqlite3pager_write”、 “sqlite3pager_pagecount”等都是老版本函数,它们在 pager.h 文件里定义。新版本对应函数是在 sqlite3.h 里定义(因为都合并到 sqlite3.c和sqlite3.h两文件了)。所以,如果你在使用老版本的sqlite,先看看 pager.h 文件,这些函数不是消失了,也不是新蹦出来的,而是老版本函数改名得到的。
1 Y! u# V. P9 I/ R5 U" s
( O( {3 S9 Y# {* M% b2 i5 w
4 Q+ m8 V- n) P
. u+ o( u0 L- T# A% S' L0 B( C0 U& B最后,往sqlite3.c 文件下找。找到最后一行:
复制内容到剪贴板
代码:
/************** End of main.c ************************************************/

在这一行后面,接上本文最下面的代码段。
6 C+ |. i! C( M( E. H5 O9 B. n& a8 o' Z1 @: `4 K
这些代码很长,我不再解释,直接接上去就得了。
- p& [. m0 Y, W$ {+ b8 u
# @5 ]2 d   v3 {2 V唯一要提的是 DeriveKey 函数。这个函数是对密钥的扩展。比如,你要求密钥是128位,即是16字节,但是如果用户只输入 1个字节呢?2个字节呢?或输入50个字节呢?你得对密钥进行扩展,使之符合16字节的要求。
4 C- ]   f& q! I5 D$ i' T
0 J7 {1 e( @3 ]/ B4 x: kDeriveKey 函数就是做这个扩展的。有人把接收到的密钥求md5,这也是一个办法,因为md5运算结果固定16字节,不论你有多少字符,最后就是16字节。这是md5 算法的特点。但是我不想用md5,因为还得为它添加包含一些 md5 的.c或.cpp文件。我不想这么做。我自己写了一个算法来扩展密钥,很简单的算法。当然,你也可以使用你的扩展方法,也而可以使用 md5 算法。只要修改 DeriveKey 函数就可以了。
3 V2 \* G. N, \$ A* s. N5 a
& J& d, ?9 B) y( g- w在 DeriveKey 函数里,只管申请空间构造所需要的密钥,不需要释放,因为在另一个函数里有释放过程,而那个函数会在数据库关闭时被调用。参考我的 DeriveKey 函数来申请内存。. ~+ Z* X8 R: C; o

- }" `+ I2 w* B" d, Y5 l* R+ ^2 {
2 E   v8 Q$ H! _+ z$ ?1 N" Y* |/ w9 D1 b
这里我给出我已经修改好的 sqlite3.c 和 sqlite3.h 文件。
& }+ |# l( |% ^8 u
) d; a5 w& v$ H如果太懒,就直接使用这两个文件,编译肯定能通过,运行也正常。当然,你必须按我前面提的,新建 crypt.h 和 crypt.c 文件,而且函数要按我前面定义的要求来做。

.4 sqlite3.c 最后添加代码段

复制内容到剪贴板
代码:
/***

董淳光定义的加密函数

***/

#ifdef SQLITE_HAS_CODEC



/***

加密结构

***/

#define CRYPT_OFFSET 8

typedef struct _CryptBlock

{

BYTE*     ReadKey;     // 读数据库和写入事务的密钥

BYTE*     WriteKey; // 写入数据库的密钥

int    PageSize; // 页的大小

BYTE*     Data;

} CryptBlock, *LPCryptBlock;



#ifndef   DB_KEY_LENGTH_BYTE       /*密钥长度*/

#define   DB_KEY_LENGTH_BYTE 16 /*密钥长度*/

#endif



#ifndef   DB_KEY_PADDING          /*密钥位数不足时补充的字符*/

#define   DB_KEY_PADDING    0x33   /*密钥位数不足时补充的字符*/

#endif
posted @ 2009-05-16 13:54  jcss  阅读(463)  评论(0编辑  收藏  举报