SQLite学习笔记(十)&&加密

     随着移动互联网的发展,手机使用愈来愈普遍,sqlite做为手机端存储的一种解决方案,使用也很是广泛。可是sqlite自己安全特性却比较弱,好比不支持用户权限,只要能获取到数据库文件就能进行访问;另外也没有加密功能,任何人获取到文件后,就能够查到明文数据。这使得你们对于sqlite又爱又不敢用,毕竟用户的隐私是很是重要的。Sqlite分为开源版本和收费版,收费的版本是支持加密的,只不过须要付2000刀的技术支持费。固然,因为sqlite自己是开源的,业内有不少产品对sqlite增长了加密功能,好比wxsqlite,sqlcipher等。所以想无偿使用加密版本的sqlite也不是不能够,但前提是使用过程遇到问题,必定要能hold住,由于免费的东西不必定是稳定的。废话少说,本文主要讨论两个问题, 1.本身如何实现sqlite的加密功能,2.如何使用加密的sqlite。算法

加密算法选择sql

     要实现加密,首先须要选择一种主流、高效、安全的加密算法,对于手机端和嵌入式设备,还要加上一条简单的原则。加密算法主要分为对称加密算法和非对称加密算法,对于文本加密通常采用对称加密,而对于秘钥的管理则采用非对称加密。目前主流的对称加密算法有DES,AES,RC系列,TEA系列, Blowfish等,非对称加密算法有RSA、Diffie-Hellman等。本人对几种常见的对称加密算法进行了测试,综合起来AES和XXTEA算法性能最好,XXTEA的优点在于实现很是简单,代码不到100行,在端设备上也是一种优点。另外,腾讯一直在使用TEA系列算法做为它的通信加密和本地存储加密,用实践证实了TEA系列算法的可靠性和安全性。下图是AES算法和XXTEA算法的一些测试数据,仅供参考。XXTEA-256和XXTEA-64,分别表示块大小是256个INT和64个INT。经过测试读写200M数据的时间来评估算法的优劣,每一个数据经过测试5次取平均值。数据库

 

不加密缓存

AES安全

XXTEA-256框架

XXTEA-64函数

写操做性能

7879.3ms测试

10283.6ms加密

10577.3ms

10649.4ms

读操做

315.69ms

3681.4ms

3527ms

3598ms

 

上层应用加密

     选择好加密算法,那么要实现加密功能了。有童鞋会问,为啥必定要在sqlite内部实现加密,上层应用加密不是同样OK吗?这个确实能够。不少开发语言都自带了加密库函数,直接调用便可。写入数据时进行加密,读出数据时再进行解密。但这种方式主要有如下几个缺点:

  1. 对于加密的数据列,没法使用索引,虽然能够用等值查询,但对于范围查询则无能为力。并且全部类型须要设计为BLOB类型,来存储密文。
  2. 虽然能够对数据列进行加密,但表的元数据没法加密。

因此,总地来讲,应用层是一种解决方案,但对开发者不太友好。

sqlite自身加密

     从原理上来看,加入加密模块功能也相对简单,在写入数据块前,调用加密模块进行数据块加密,而后写入文件;而在读取数据块时,先调用加密模块解密,而后加载到缓存。加密模块(红色标注)在整个sqlite实现框架的位置以下图。

 

实现层面,咱们要作的工做主要包括三部分,实现加密算法,而后将加密接口与sqlite关联起来,最后在合适的位置(读写文件),调用加/解密接口完成加密解密工做。因为sqlite自身已经预留了加解密接口,所以第3部分的工做已经帮咱们作了,咱们只须要实现第1和第2部分工做。核心接口以下:

    1.sqlite3CodecAttach 

含义:调用sqlite3PagerSetCodec 将加密接口与sqlite的pager模块关联

    2.xxxCodec

含义:本身定义的加密接口,输入参数是(page_no,读写模式),将指定page加、解密。

    3.sqlite3_key

含义:设置数据库密钥,sqlite3_open后调用该接口。对于非加密库,若调用该接口,会致使后续访问数据报错。

Error: file is encrypted or is not a database

    4.sqlite3_rekey

含义:修改数据库密钥,这个接口会遍历数据库中的全部页,而后用新密钥对页进行加密,写入文件。若将新密钥设置为NULL,则能够将加密库变为普通库。

    5.sqlite3_activate_see

       sqlite3CodecGetKey

这两个接口没有实际做用,能够实现一个空函数,保证能编译经过就行。

加密sqlite使用

若是顺利,咱们如今已经有了一个包含加密功能的sqlite了,那么如何使用?下面主要列了一些常见的场景。

   1.如何判断一个db文件是否加密

$sqlite3 ./data/test.db

sqlite> .tables Error: file is encrypted or is not a database 

sqlite> pragma key='123456' ;

sqlite> .tables

Error: file is encrypted or is not a database 

对于加密的db文件,若是没有执行pragma key=xxx命令直接执行,则会报错。假设密码是 123456,报错后,从新执行pragma key命令,而后执行.tables,这时候依旧报错。这个主要是由于密钥在链接建立时初始化,因此对于加密数据库,须要执行的第一条命令是pragma key=xxx 

    2.导出加密文件数据

$sqlite3 ./data/test.db // 打开加密数据库文件test.db

sqlite> pragma key='123456';   // 设置秘钥   

sqlite> .output aaa.sql //将输出重定向到文件aaa.sql

sqlite> .dump //导出数据库

sqlite> .exit   这样aaa.sql中包含了test.db中数据库的明文内容。

    3.解密加密数据库

$sqlite3 ./data/test.db

sqlite> pragma key='123456'

sqlite> pragma rekey='';  //设置密钥为空,则将密文数据库解密。   

 

//解密后能够直接打开数据库   

$sqlite3 ./data/test.db

sqlite> .tables

  • orders  t1  user  

sqlite> .exit 

参考文档

https://en.wikipedia.org/wiki/XXTEA

相关文章
相关标签/搜索