Android sqlcipher数据库解密流程

590 阅读2分钟

背景:支持的一个业务经常有用户反馈存储在数据库中的数据有丢失问题,分析有多个地方可能都会存在问题,一个一个的排查。

大概就是2种数据被清空的根本原因:

  • 数据库文件(xxx.db)被删除了。
  • 数据库表中的记录被清空了。

分析:

针对第一种清空,如果是数据库文件(xxx.db)被删除后重建,新插入记录的时候,id字段的值应该是从1开始。如果是数据库表中的记录被删除了,新插入的数据id字段应该不是从1开始。

前提:

  • 准备数据库密码。
  • xxx.db数据库文件。

密码回收: 如果数据库密码是固定密码的话,不用回收,如果数据库密码是动态密码,需要把密码回收回来(通过写入到文件、页面、上传服务器等方式)。

db文件回收:db文件在应用目录下,非root权限的手机无法直接读取,可以复制到外置sdcard后读取,或者线上环境能够上传到服务器方式回收。

2个条件都具备后进行如下操作(Mac):

1、sqlcipher安装, brew install sqlcipher

2、用终端切换到数据库的路径下,命令 cd /Users/xxxxxxx

3、输入 sqlcipher xxxxx.db ,按Enter键继续

4、提示“Enter SQL statements terminated with a ";"” 时,输入 PRAGMA key='123456';     // 123456为密码 按Enter键继续

5、输入 ATTACH DATABASE ‘plaintext.db' AS test KEY '';   按Enter键继续

6、输入 SELECT sqlcipher_export('test'); 按Enter键继续

7、DETACH DATABASE test;

8、生成的 test.db 即为解密后的数据库,可直接打开

android Sqlite3 打开数据库:

系统命令

sqlite test.db              创建test.db文件并进入sqlite3
sqlite>.database            查看数据库文件信息命令(注意命令前带字符'.')
sqlite>.schema              查看所有表的创建语句:
sqlite>.schema table_name   查看指定表的创建语句:
sqlite>.dump table_name     以sql语句的形式列出表内容:
sqlite>.separator symble    设置显示信息的分隔符:
sqlite>.separator :         设置显示信息以‘:'分隔
sqlite>.mode mode_name      设置显示模式:
sqlite>.mode column         默认为list,设置为column,其他模式可通过.help查看mode相关内
sqlite>.help                输出帮助信息:
sqlite>.width width_value   设置每一列的显示宽度:
sqlite>.width 2             设置宽度为2
sqlite>.show                列出当前显示格式的配置
sqlite>.quit     或   sqlite>.exit     退出sqlite终端命令:

sql命令:

例如查看数据库表记录: select * from table_name;

其他操作可用标准sql脚本。

SQLITE写入大量大数据时,报错ERR 11:database disk image is malformed

sqlitecipher test.db 回车
PRAGMA key='123456';     // 123456为密码
sqlite>PRAGMA integrity_check

报错ERR 11:database disk image is malformed.

sqlite>.output test.sql
sqlite>.dump
sqlite>.quit

导出所有为sql文件。

分析sql脚本,或者抽取相关数据表为单独的sql文件:

cat test.sql | grep "table_name" > table_name.sql

导入table_name.sql,

sqlite3 test_table_name < table_name.sql

生成test_table_name.db文件

sqlite3 test_table_name.db  // 打开数据库

sqlite> select * from table_name; // 查看所有的记录