admin 管理员组

文章数量: 1184232


2024年3月13日发(作者:php com组件)

SQLite的加密扩展方法

这篇文章专门介绍如何扩展当前正越来越流行SQLite的数据库的加密部分, SQLite是

"一个无须任何配置部署的嵌入式SQL数据库."

背景

我为什么要写这个扩展? 为了满足我自己的一些疯狂的想法. :) 好了,不开玩笑了. 不

久前我想写一个程序用来存储一些私人信息 (我自己的一个项目). 我不想用那些很大的开

源数据库,例如MySQL,因为它们确实是太大了,需要占用很大的空间,而且要单独的安装部

署. 后来我发现了 SQLite, 它非常的小巧而且运行起来很快,并且它的API函数十分的简

单,在我的C++程序当中可以很方便的使用. 就是有一个问题,大概是由于它要保持简单所

以它不支持任何的验证和加密. 这令我一点安全感都没有.

因此我开始寻找SQLite的加密 解决方案. 我找到了两个,但是它们都是商业软件.

SQLite的作者, D. Richard Hipp先生提供了一个可以对数据库文件进行完全加密SQLite

的加强版本. 也就是那个叫做SQLcrypt(tm)的商业软件, 它实现了数据存储层的透明加密.

不幸的是它们对于我们这些普通人来说都太贵了, 尤其是对于我这种非商业目的只是想用

SQLite开发一些小应用自己玩的人来说更是如此. 然而我却是非常的需要对数据库进行加

密- 在数据库层对整个数据库文件进行透明的加密. 所有的开发者和用户只需要在打开数

据库的时候提供密码就可以了. 然后接下来的事情就全都交给数据库去做了. 这种方式将

比那种在数据和字段上的加密要容易的多,也方便的多, 不然需要加密的字段就都要设计成

BLOB或者string类型了.

在我搜索了SQLite的邮件列表和在Google上搜索免费的SQLite插件或扩展之后,

我发现没有能够满足我的需求的, 所以我决定自己写一个. 我从SQLite的作者预留的一些

用来支持数据库加密解密的API接口获得了灵感,并且我发现实际上也有人写了一个基于

SQLite的加密库 (SQLcrypt). 我花费了几天的时间来研究一些加密的算法,我要选出一种

使用(The AES (Rijndael) block cipher) ,另外还有就是如何生成密码, 当然最重要的就是

我怎样才能把我用来完成加密解密数据库的代码嵌入SQLite的核心当中执行.

扩展模块的技术说明书

这个扩展模块的结构相当的简单. 大体上来说我编写了SQLite代码中已经提供了原型

的四个函数: sqlite3_key(), sqlite3_rekey(), sqlite3CodecGetKey(), 和

sqlite3CodecAttach(). 前两个函数是在sqlite3.h头文件中定义的公共API. 另外两个定

义在 attach.c 的sqlite3Attach()函数中. 我阅读了它的源代码中提供的函数原形(主要是

pager.c 和 btree.c两个文件),看一下它们是如何工作的. 我发现实现他们并不困难,因

为对数据库加密解密的机制已经都实现了(感谢 Richard!).

这个扩展的其他部分就是写一个用来加密 和解密的程序. 为此我使用了AES加密算

法,其中代码的关键部分取自Brian Gladman (his site) 还有David Ireland的高精度加

密算法库BigDigits. 因为我不想在一开始的时候就跟SQLite的数据库格式过多的纠缠,

所以我用了计数器模式(CTR)把AES加密块转换成256字节的加密流. 这样加密之后的密

文就可以和原来的明文有相同的长度,加密和没加密的数据库文件尺寸相同 (也就是说不

需要保存而外的信息). 我还使用了Brian Gladman网站上提供的 PKCS#5签名的

SHA256算法从用户提供的密码中来生成AES 算法的密钥. 如果是这样的话, 我就要写很

多的代码来处理salt value 才能避免往数据库中存入额外的信息.

Pager结构体用来存放指向编码函数的指针, 用来从数据库中加密或解密数据. 我写


本文标签: 加密 数据库 用来 提供 扩展