当前位置: 首页 > news >正文

关于SQLite,SQLCipher和FMDB

SQLite是一个轻量的、跨平台的、开源的数据库引擎,它的在读写效率、消耗总量、延迟时间和整体简单性上具有的优越性,使其成为移动平台数据库的最佳解决方案(如iOS、Android)。然而免费版的SQLite有一个致命缺点:不支持加密。这就导致存储在SQLite中的数据可以被任何人用任何文本编辑器查看到。

  如果我们想要使得自己的数据库加密,解决方案就是使用另一款开源的加密数据库SQLCipher,SQLCipher使用256-bit AES加密,由于其基于免费版的SQLite,主要的加密接口和SQLite是相同的,当然也增加了一些自己的接口,如在新建和打开数据库时,给数据库设置秘钥之类的操作。

  FMDB是一个开源的类库,它对sqlite数据库操作进行了很不错的封装,而且也增加了对sqlcipher的支持,也就是说,我们不直接用sqlcihper也能完成加解密操作,而且FMDB在操作sqlite方面方便得多。现在的APP开发如果涉及到数据库操作,FMDB基本上是首选。

  下面内容主要是针对一些在初期忽略了数据库私密性,而到了中期需要让数据库进行升级加密的App的简单方案介绍和代码实现。如果读者没有使用FMDB,直接使用了sqlite,那本文也有一定参考性,只是关于SQLCipher的配置,并没有介绍,因为虽然FDMB的加密也是使用SQLCipher,但是不需要进行配置的。

  具有加密功能的FMDB版本

  加密的FMDB其实是一个分支,也就是说,如果你需要替换FMDB。Github上关于该分支的安装只提供了cocospod的安装方式。

  Github上FMDB的地址:https://github.com/ccgus/fmdb

  

  举个例子,如果你以前是如下写的

1
pod  'FMDB'

  如果想换成有加密功能的,就改成

1
pod  'FMDB/SQLCipher'

  升级数据库代码实现

  得到对的版本后,我们需要在代码里做一些处理,让旧数据库升级。这里升级包括两点:

  1 是我们前面所说的,将数据库加密。

  2 把旧数据库的表和数据迁移到新数据库中。

  sqlcipher的使用和sqlite没有多大的区别,有一点值得注意便是每次当[dp open]成功后,需要给数据库配上口令,即[db setKey:DB_SECRETKEY], DB_SECRETKEY是我们的一个自定义宏。这之后,我们才能读出数据库的内容。

1
2
3
4
5
6
7
FMDatabase  * _db  =  [FMDatabase databaseWithPath:[cachePath stringByAppendingString:dbFileName]];
if  (![_db  open ]) {
     _db  =  nil;
     return ;
} else {
     [_db setKey:DB_SECRETKEY];
}

  然后我们需要判断数据库是否需要升级,当使用sqlchipher打开用sqlite生成的源数据库时,[dp goodConnection]是为NO,即使上面[db open]操作是YES。

1
2
3
if (![_db goodConnection]){  //无效连接
     [ self  upgradeDatabase:dbpath];
}

  接下来,便是数据迁移,path是我们的源数据库路径,假设我们的源数据库名字为DBName,changeDatabasePath即将我们的数据库A改名为DBName.tmp,接下来便是,新建数据库B,因为A在前面已经进行了改名为DBName.tmp,并且已经B将来就是我们要取代A的数据库,所以此处的B名字便是DBName。最后将DBName.tmp的数据复制到DBName中,再删除DBName.tmp,致此,我们的数据库便升级完成了。


  经过上面步骤,我们知道虽然sqlchipher是基于sqlite的,但到底还是不一样的,我们没办法直接将sqlite的数据库升级为sqlchipher,只能用sqlchipher新建一个数据库,再重新写入数据。  

  以上代码仅仅是范例,各个App的数据存储模型不尽相同,这里我也没办法给出模板。虽然代码不一定是适用的,但是在数据库升级时,代码执行的先后顺序是肯定的:打开数据库open -> 设置秘钥 setkey -> 查看连接 goodConnection -> 新建数据库并迁移数据 upgrade。












本文转自ljianbing51CTO博客,原文链接:http://blog.51cto.com/ljianbing/1903079 ,如需转载请自行联系原作者


相关文章:

  • Android自定义组合控件
  • js判断客户浏览器类型,版本
  • Eclipse Deepin 12.12 代码提示崩溃
  • 做技术到底可以做到哪种地步-技术为什么越走越窄
  • linux转发流程图。
  • Java连接Mysql,SQL Server, Access,Oracle
  • 毕业那点事儿--回顾在大学这7年
  • Engineer01
  • 7款拥有超酷设计灵感的动态网站设计
  • 这才叫电脑高手!
  • 必应搜索全球PK,只为证明自己
  • 关于glusterfs-3.3.1的两个bug
  • 老树新芽,在ES6下使用Express
  • 工作那些事儿(5)- 机会
  • ASP.NET中Html.Partial和Html.Action的一个区别
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • ECMAScript6(0):ES6简明参考手册
  • js中forEach回调同异步问题
  • Linux快速复制或删除大量小文件
  • MySQL主从复制读写分离及奇怪的问题
  • React16时代,该用什么姿势写 React ?
  • SegmentFault 2015 Top Rank
  • Sequelize 中文文档 v4 - Getting started - 入门
  • Vue.js-Day01
  • webpack入门学习手记(二)
  • 缓存与缓冲
  • 看域名解析域名安全对SEO的影响
  • 坑!为什么View.startAnimation不起作用?
  • 巧用 TypeScript (一)
  • 中文输入法与React文本输入框的问题与解决方案
  • 主流的CSS水平和垂直居中技术大全
  • 你对linux中grep命令知道多少?
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 如何在招聘中考核.NET架构师
  • #QT(一种朴素的计算器实现方法)
  • $.ajax()参数及用法
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (五)MySQL的备份及恢复
  • (转)setTimeout 和 setInterval 的区别
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .Net Web项目创建比较不错的参考文章
  • .net 程序发生了一个不可捕获的异常
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .NET微信公众号开发-2.0创建自定义菜单
  • [22]. 括号生成
  • [AHOI2009]中国象棋 DP,递推,组合数
  • [Android]使用Retrofit进行网络请求
  • [C++]二叉搜索树