SQLite是一款被设计用于嵌入式设备的轻型的数据库,是遵守ACID的关联式数据库管理系统,它具有存储效率高、查询快、运行时占用内存小、能被多进程同时访问以及单文件存储数据库内容等优点。SQLite中文官方网站上列举了SQLite的如下特点:
1. ACID事务
2. 零配置 – 无需安装和管理配置
3. 储存在单一磁盘文件中的一个完整的数据库
4. 数据库文件可以在不同字节顺序的机器间自由的共享
5. 支持数据库大小至2TB
6. 足够小, 大致3万行C代码, 250K – (下载了最新源码好像有12万行了)
7. 比一些流行的数据库在大部分普通数据库操作要快
8. 简单, 轻松的API
9. 包含TCL绑定, 同时通过Wrapper支持其他语言的绑定
10. 良好注释的源代码, 并且有着90%以上的测试覆盖率
11. 独立: 没有额外依赖
12.Source完全的Open, 你可以用于任何用途, 包括出售它
13. 支持多种开发语言,C, PHP, Perl, Java,ASP .NET,Python
为了满足嵌入式系统对数据库本身的轻便性,以及对数据存储效率、访问速度、内存占用率等性能的要求,SQLite 采取了不同于大型数据库的实现机制,但同时也带来了一些潜在的安全隐患。SQLite不提供网络访问服务,它使用单一文件存储数据库的结构和内容,这使得数据库非常轻便,而且便于移植。数据库没有用户管理、访问控制和授权机制,它利用操作系统对文件的访问控制能力实施文件级别的访问控制,即:凡是操作系统的合法用户,只要该用户对数据库文件具有读/写权限,就可以直接访问数据库文件。开源SQLite 数据库不提供加密机制,因此不提供数据级的保密性。此外,SQLite 的存储格式简单,不需专门的工具,使用任何文本编辑器都可以查看文件的内容。由于不提供多用户机制,所以数据库没有审计机制,而且它的备份和恢复也只能依赖于对数据库文件的手工拷贝。总之,SQLite的安全机制非常薄弱。
SQLite数据库设计中考虑了安全问题并预留了加密相关的接口。但是并没有给出实现。SQLite 数据库源码中通过使用SQLITE_HAS_CODEC宏来控制是否使用数据库加密。并且预留了四个结构让用户自己实现以达到对数据库进行加密的效果。这四个接口分别是:
sqlite3_key(): 指定数据库使用的密钥
sqlite3_rekey():为数据库重新设定密钥用于为数据库重新设定密钥;
sqlite3CodecGetKey():返回数据库的当前密钥
sqlite3CodecAttach(): 将密钥及页面编码函数与数据库进行关联。
要实现SQLite 数据库的加密功能,需要给出这几个关键函数的具体实现,同时还要提供数据加解密函数、页面编码函数等必备函数
Android系统中也引入了SQLite进行数据存储管理,并在FrameWrok层对SQLite提供的一些功能进行了封装,提供了如下相关的接口供用户调用。
SQLiteCursor
SQLiteDatabse
SQLiteOpenHelper
SQLiteProgram
SQLiteQuery
SQLiteQueryBuilder
SQLiteStatement
Android数据库访问框架图如下所示:
从这个架构可以看到,我们如果需要对数据库进行加密并将接口,需要修改libsqlite.so,libandroid_runtime.so以及SQLiteDatabase这几个地方。
目前主流的数据库都采用了各种安全措施,主要包括用户认证、访问控
制、数据加密存储和数据库操作审计等措施。
用户认证:用户或者程序向数据库提供自己的有效身份证明,数据库鉴别用户的身份是否合法,只有合法的用户才能存取数据库中的数据。用户认证是所有安全机制的前提,只有通过认证才能进行授权访问和审计。
访问控制:数据库管理系统为不同的用户分配不同的权限,保证用户只能进行授权的访问。目前,一些大型数据库(如Oracle 等)都采用了基于角色的访问控制机制,即为用户授予不同的角色,如db—owner,security administrator 等,不同的角色允许对数据库执行不同的操作。
数据库加密:用户认证以及访问控制对访问数据库进行了控制,但攻击者可能会利用操作系统或数据库漏洞,或物理接触计算机,而直接接触数据库系统文件,从而可能绕过身份认证和存取控制而直接窃取或篡改数据库内容。对数据库中的数据进行加密是防范这类威胁的有效手段。
数据库操作审计:监视和记录用户对数据库所做的各种操作的安全机制,它记录并存储用户的操作,用于事后分析,以检查导致数据库现状的原因以及提供追踪攻击者的线索。数据库的备份与恢复:当数据库发生不可恢复的故障时,可以将数据库恢复到先前的某个一致性的状态。
由于SQLite 是开放源码的,并且在其源码中预留了加密接口,我们可以通过实现其预留的加密接口实现口令认证和数据库加密以完善其加密机制。
SQLite 数据库文件是一个普通文本文件,对它的访问首先依赖于文件的访问控制。在此基础上,再增加进一步的口令认证,即在访问数据库时必须提供正确的口令,如果通过认证就可以对数据库执行创建、查询、修改、插入、删除和修改等操作;否则,不允许进一步的访问。
数据库加密有两种方式:
1)在数据库管理系(Data Base Management System,DBMS)中实现加密功能,即在从数据库中读数据和向数据库中写数据时执行加解密操作;
2)应用层加密,即在应用程序中对数据库的某些字段的值进行加密,DBMS 管理的是加密后的密文。
前者与DBMS 结合好,加密方式对用户透明,但增加了DBMS 的负载,并且需要修改DBMS的原始代码;后者则需要应用程序在写入数据前加密,在读出数据后解密,因而会增大应用程序的负载。在此,通过实现SQLite 源码中预留的加密接口,实现DBMS 级的加密。
微型加密算法(TEA)及其相关变种(XTEA,Block TEA,XXTEA) 都是分组加密算法,它们很容易被描述,实现也很简单(典型的几行代码)。
TEA 算法最初是由剑桥计算机实验室的 David Wheeler 和 Roger Needham在 1994 年设计的。该算法使用 128 位的密钥为 64 位的信息块进行加密,它需要进行 64 轮迭代,尽管作者认为 32 轮已经足够了。该算法使用了一个神秘常数δ作为倍数,它来源于黄金比率,以保证每一轮加密都不相同。但δ的精确值似乎并不重要,这里 TEA 把它定义为 δ=「(√5 - 1)231」(也就是程序中的 0×9E3779B9)。
之后 TEA 算法被发现存在缺陷,作为回应,设计者提出了一个 TEA 的升级版本——XTEA(有时也被称为“tean”)。XTEA 跟 TEA 使用了相同的简单运算,但它采用了截然不同的顺序,为了阻止密钥表攻击,四个子密钥(在加密过程中,原 128 位的密钥被拆分为 4 个 32 位的子密钥)采用了一种不太正规的方式进行混合,但速度更慢了。
在跟描述 XTEA 算法的同一份报告中,还介绍了另外一种被称为 Block TEA 算法的变种,它可以对 32 位大小任意倍数的变量块进行操作。该算法将 XTEA 轮循函数依次应用于块中的每个字,并且将它附加于它的邻字。该操作重复多少轮依赖于块的大小,但至少需要 6 轮。该方法的优势在于它无需操作模式(CBC,OFB,CFB 等),密钥可直接用于信息。对于长的信息它可能比 XTEA 更有效率。
在 1998 年,Markku-JuhaniSaarinen 给出了一个可有效攻击 Block TEA 算法的代码,但之后很快 David J. Wheeler 和 Roger M.Needham 就给出了 Block TEA 算法的修订版,这个算法被称为 XXTEA。XXTEA 使用跟 Block TEA 相似的结构,但在处理块中每个字时利用了相邻字。它利用一个更复杂的 MX 函数代替了 XTEA 轮循函数,MX 使用 2 个输入量。