首先iOS 8.3之前是直接可以拿到app沙盒里面的数据库的,之后应该也是有方法能拿到(待定,需要试试),所以还是需要对本地的数据库加密。
通用数据库加密方式:
1.对所有的数据加密
2.直接对数据库加密
第一个方法的话对于我们来说,数据库储存的内容极多,并且加密之后不便于我们自己查询,所以采用第二种方式。
集成:
之前因为小影直接用的是 pod'FMDB','~> 2.6',
现在:pod'FMDB/SQLCipher','~> 2.7.2'
原理:
SQLite数据库加解密
首先需要从gitHub上下载SQLCipher的源码:
github.com/sqlcipher/sqlcipher
SQLCipher提供了几个命令用于加解密操作
加密:
sqlcipher xiaoying.db
sqlite> ATTACH DATABASE 'xiaoyingEncrypt.db' AS xiaoying KEY '123456';
sqlite> SELECT sqlcipher_export('xiaoying');
sqlite> DETACH DATABASE xiaoying;
1.打开未加密的数据库
2.创建一个新的xiaoyingEncrypt.db附加到原数据库上
3.导出数据到新的数据库上
4.卸载新的数据库
解密:
sqlcipher xiaoyingEncrypt.db
sqlite> PRAGMA key = '123456';
sqlite> ATTACH DATABASE 'xiaoying.db' AS xiaoyingEncrypt KEY '';
-- 空的密码就禁用密码了
sqlite> SELECT sqlcipher_export('xiaoyingEncrypt');
sqlite> DETACH DATABASE xiaoyingEncrypt;
1.打开xiaoyingEncrypt.db
2.输入密码
3.创建一个新的加密的数据库附加到原数据库上
4.导出数据到新的数据库
5.卸载新的数据库
其他:
还有修改密码之类的可以自行了解了解,都很简单。
开始加密:
查询说是在数据库open之后设置一个密码就行,实测就是扯淡。
我们本来是一个没有加密的数据库,所以直接setKey是没有用的。只能通过升级数据库来加密。
小影本身本地有数据库,所以需要对本地的空的数据库先加密,然后对于卸载了新安装的用户,直接setKey 就哦了。
数据库升级:
对于原本就安装然后升级上来的用户,因为本地本身存在未加密的数据库,所以需要去重新通过SQLCipher去新建替换掉旧的未加密的数据库。
所以在setKey之后还需要:
判断数据库是否需要升级,当使用sqlchipher打开用sqlite生成的源数据库时,[self goodConnection]是为NO,即使openWithFlags或者open操作是YES。
if(![self goodConnection]) {
// 无效链接
[self upgradeDatabase:self.databasePath];
}
如果goodConnection 返回NO,则说明需要数据迁移,基本的思路就是:
1.修改之前的未加密数据库名字
2.打开旧的数据库
3.创建一个新的db附加到原数据库上
4.导出数据到新的数据库上
5.卸载新的数据库
6.删除旧的数据库
总的加密思路:
1.open db
2.setKey
3.check goodConnection,如果返回NO 就去数据迁移
4.DONE
数据库升级出错解决方案:
!!!但是,小影这边在数据库升级迁移这边,有三个数据库,最后一个xiaoying.db 路径需要从另外一个数据库中取出一个workFolderName,实测在取这个name的时候前两次是必取不出来,第三次之后才能取到,暂时未找到为什么。所以在已经存在数据库的情况下,也就是用户是升级App的情况下不会去setKey。(暂时的解决方法)数据库升级的时候,在goodConnection 返回NO的时候,也就是数据库升级的时候,需要先调用close方法,在调用open方法,我的理解是先把旧的数据库关闭再打开新的加密后的数据库,这样才能正常的读取加密后的数据。
我们之前打开数据库用的是mesaSQLite,但是加密了之后就算你输入密码也不能打开,原因不明...
所以找了一个能打开的 DB Browser for SQLite... 实测可以打开。