一 一个简短的引论  

SQLite是一个轻量的、跨平台的、开源的数据库引擎。它的读写效率、资源消耗总量、延迟时间和总体简单性上具有的优越性,使其成为移动平台数据库的最佳解决方式(如Android、iOS)。

Android系统内置了SQLite数据库。而且提供了一整套的API用于对数据库进行增删改查操作。具体就不具体说明了。

然而。Android平台自带的SQLite有一个致命的缺陷:不支持加密。这就导致存储在SQLite中的数据能够被不论什么人用不论什么文本编辑器查看到。假设是普通的数据还好,可是当涉及到一些账号password,或者聊天内容的时候,我们的应用就会面临严重的安全漏洞隐患。

二 解决方式

1.SQLite加密方式
对数据库加密的思路有两种:
将内容加密后再写入数据库
       这样的方式使用简单。在入库/出库仅仅须要将字段做相应的加解密操作就可以,一定程度上攻克了将数据赤裸裸暴露的问题。
只是这样的方式并非彻底的加密。由于数据库的表结构等信息还是能被查看到。另外写入数据库的内容加密后,搜索也是个问题。

对数据库文件加密
       将整个数据库整个文件加密,这样的方式基本上能解决数据库的信息安全问题。眼下已有的SQLite加密基本都是通过这样的方式实现的。

2.SQLite加密工具

今天我们要说的是一款开源的SQLite加密工具 SQLCipher。SQLCipher是全然开源的,其代码托管在github上。

SQLCipher使用256-bit AES加密,因为其基于免费版的SQLite,基本的加密接口和SQLite是同样的,但也添加了一些自己的接口。

其实SQLite有加解密接口,仅仅是免费版本号没有实现而已。

SQLCipher分为Community Edition 和 Commercial Edition,前者是免费的,关于  SQLCipher Features 能够參看这里。

关于跨平台支持,官方说明例如以下:

SQLCipher has broad platform support for with C/C++, Obj-C, QT, Win32/.NET, Java, Python, Ruby, Linux, Mac OS X, iPhone/iOS, Android, Xamarin.iOS, and Xamarin.Android(如iOS、Android)。

同一时候支持 Android、iOS 两大平台。

3.SQLCipher集成

SQLCipher官方提供了具体的集成说明文档,具体參看这里。

以下通过一个简单的演示样例演示怎样高速集成SQLCipher到我们的项目中。

3.1 下载官方二进制文件包

下载地址:https://s3.amazonaws.com/sqlcipher/3.2.0/sqlcipher-for-android-community-v3.2.0.zip

3.2 导入依赖文件

将下载的后的压缩包解压,解压后例如以下所看到的:

将libs 和 assets文件夹下的全部文件复制到我们当前的project中来,拷贝完毕后例如以下:

3.3 操作数据库

首先,自己定义MySQLiteOpenHelper 继承自 net.sqlcipher.database.SQLiteOpenHelper类,而不是android.database.sqlite.SQLiteOpenHelper,切记!演示样例代码例如以下:

package com.ricky.android.sqlitecipher.db;import com.ricky.android.sqlitecipher.util.Logger;
import android.content.Context;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabase.CursorFactory;
import net.sqlcipher.database.SQLiteOpenHelper;public class MySQLiteOpenHelper extends SQLiteOpenHelper {private static final String DB_NAME = "test.db";private static final int DB_VERSION = 3;public MySQLiteOpenHelper(Context context){super(context, DB_NAME, null, DB_VERSION);}public MySQLiteOpenHelper(Context context, String name,CursorFactory factory, int version) {super(context, name, factory, version);}@Overridepublic void onCreate(SQLiteDatabase db) {Logger.e("MySQLiteOpenHelper", "onCreate db name="+DB_NAME+" version="+DB_VERSION);db.execSQL("CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT, name text, age integer)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {// TODO Auto-generated method stub}}

然后在我们的DAO类中使用 SQLiteDatabase操作数据库。注意,此处是net.sqlcipher.database.SQLiteDatabase,而不是android.database.sqlite.SQLiteDatabase。千万不要引错包了!

package com.ricky.android.sqlitecipher.dao;import java.util.ArrayList;
import java.util.List;
import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;
import android.content.ContentValues;
import android.content.Context;
import com.ricky.android.sqlitecipher.db.SQLiteHelperFactory;
import com.ricky.android.sqlitecipher.model.Student;public class StudentDAOImpl implements StudentDAO {private SQLiteOpenHelper sqLiteOpenHelper;private String password = "ricky";public StudentDAOImpl(Context context){sqLiteOpenHelper = SQLiteHelperFactory.create(context);}@Overridepublic long insert(Student stu) {SQLiteDatabase db = null;try{db = sqLiteOpenHelper.getWritableDatabase(password);ContentValues values = new ContentValues();  values.put("name", "Ricky");  values.put("age", 24);  return db.insert("student", null, values);}finally{if(db!=null)db.close();}}@Overridepublic List<Student> query() {SQLiteDatabase db = null;Cursor cursor = null;try{db = sqLiteOpenHelper.getWritableDatabase(password);cursor = db.query("student", new String[]{"id","name","age"}, null, null, null, null, null);List<Student> list = new ArrayList<>();while(cursor!=null && cursor.moveToNext()){Student stu = new Student();stu.setId(cursor.getInt(0));stu.setName(cursor.getString(1));stu.setAge(cursor.getInt(2));list.add(stu);}return list;}finally{if(cursor!=null){cursor.close();}if(db!=null)db.close();}}}

到这里数据的crud基本上实现了,可是还需注意一点:必须先调用SQLiteDatabase.loadLibs(context);然后再运行数据库相关的操作。

为了方便管理,我单独写了一个 SQLiteHelperFactory类来负责SQLiteOpenHelper的创建,在创建MySQLiteOpenHelper对象之后将调用SQLiteDatabase.loadLibs(context);,代码例如以下:

package com.ricky.android.sqlitecipher.db;import com.ricky.android.sqlitecipher.util.Logger;import android.content.Context;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;/*** SQLiteOpenHelper 工厂* @author Ricky**/
public class SQLiteHelperFactory {private static final String TAG = SQLiteHelperFactory.class.getSimpleName();private static SQLiteOpenHelper sqLiteOpenHelper;private SQLiteHelperFactory(){}public static SQLiteOpenHelper create(Context context){if(sqLiteOpenHelper==null){synchronized (SQLiteHelperFactory.class) {if(sqLiteOpenHelper==null){Logger.e(TAG, "init SQLiteOpenHelper");sqLiteOpenHelper = new MySQLiteOpenHelper(context.getApplicationContext());Logger.e(TAG, "SQLiteDatabase loadLibs");//必须先调用此方法SQLiteDatabase.loadLibs(context);}}}return sqLiteOpenHelper;}
}

最后是 MainActivity类

package com.ricky.android.sqlitecipher;import java.util.List;import com.ricky.android.sqlitecipher.dao.StudentDAO;
import com.ricky.android.sqlitecipher.dao.StudentDAOImpl;
import com.ricky.android.sqlitecipher.model.Student;
import com.ricky.android.sqlitecipher.util.Logger;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {private static final String TAG = MainActivity.class.getSimpleName();private Button bt_insert;private Button bt_query;private StudentDAO studentDAO;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById();setListener();processLogic();}private void findViewById() {bt_insert = (Button) findViewById(R.id.bt_insert);bt_query = (Button) findViewById(R.id.bt_query);}private void setListener() {bt_insert.setOnClickListener(this);bt_query.setOnClickListener(this);}private void processLogic() {studentDAO = new StudentDAOImpl(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.bt_insert:Student stu = new Student();stu.setName("Mike");stu.setAge(24);long id = studentDAO.insert(stu);Logger.i(TAG, "insert id="+id);break;case R.id.bt_query:List<Student> list = studentDAO.query();if(list!=null){Logger.i(TAG, "student list size="+list.size());}else{Logger.i(TAG, "student list is empty");}break;default:break;}}
}

OK,关于SQLCipher的集成到这里就大功告成啦,最后另附Demo源代码(下载地址见文章末尾),有问题的话能够留言进行交流咯!

Demo下载地址:http://download.csdn.net/detail/fx_sky/8165223

版权声明:本文博主原创文章。博客,未经同意不得转载。

转载于:https://www.cnblogs.com/mengfanrong/p/4817686.html

Android 数据库加密相关推荐

  1. android sqlcipher github,Android应用开发Android 数据库加密 SQLCipher使用方法

    Android 数据库加密 SQLCipher使用方法 最近在做数据库加密,遇到了些问题,特此记录 greendao 支持数据库加密 网址https://greenrobot.org/greendao ...

  2. android sqlcipher 加密,Android 数据库加密 SQLCipher使用方法

    android sqlcipher使用方法 最近在做数据库加密,遇到了些问题,特此记录 greendao 支持数据库加密 网址https://greenrobot.org/greendao/docum ...

  3. Android数据库加密与破解(Xposed hook SQLCipher 密码)

    Xposed hook SQLCipher 密码 什么是SQLCipher HOOK加密的原理 介绍 原理 开始使用 下载安装模块 运行ADB命令 启动待解密的APP 在Windows下解密 下载wi ...

  4. android数据库文件是否加密存储,详解Android数据存储之SQLCipher数据库加密

    前言: 最近研究了Android Sqlite数据库以及ContentProvider程序间数据共享,我们清晰的知道Sqlite数据库默认存放位置data/data/pakage/database目录 ...

  5. Android数据库加解密逆向分析(三)——微信数据库密码破解

    接着上一篇文章,在上一篇文章中我们通过对Line数据库加密的逆向分析,了解到了对要写入到数据库中的数据加密,读取时再将读取出的数据解密这种Android上的数据库加密方式.这篇文章来通过介绍对微信数据 ...

  6. 利用SQLChiper对Android SQLite数据库加密

    利用SQLChiper对Android SQLite数据库加密 前言: 上篇文章讲了Android studio+SQLCipher加密SQLite数据库的几个坑,跳过这几个坑,那么SQLCipher ...

  7. android sqlite加密数据库,Android Sqlite数据库加密

    Android使用的是开源的SQLite数据库,数据库本身没有加密,加密思路通常有两个: 1. 对几个关键的字段使用加密算法,再存入数据库 2. 对整个数据库进行加密 SQLite数据库加密工具: 收 ...

  8. android sqlite数据库加密,(转)SQLite数据库的加密

    1.创建空的SQLite数据库. //数据库名的后缀你可以直接指定,甚至没有后缀都可以 //方法一:创建一个空sqlite数据库,用IO的方式 FileStream fs = File.Create( ...

  9. [DB那些事]数据库加密

    说到数据库加密,目前最好且唯一的方案就是SqlCipher对sqlite3整体加密,微信也用的它.开源,且支持很多平台. 单就Android来说,集成不算太麻烦,1个jar包,3个so库,1个zip. ...

最新文章

  1. MySQL半同步安装以及参数
  2. 全面对比,深度解析 Ignite 与 Spark
  3. EntityFramework 7.0之初探【基于VS 2015】(十)
  4. 弗林德斯大学计算机科学,想成为IT大神?就去学习弗林德斯大学计算机科学专业...
  5. win10网络不出现计算机列表,win10网络发现已关闭网络计算机和设备不可见怎么办?...
  6. 入门Java你需要了解的几个知识要点!
  7. Spring Boot使用layui的字体图标时无法正常显示 解决办法
  8. 学好Windows编程要看的书籍
  9. BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)
  10. 杨校老师课堂之Hadoop环境搭建(一)
  11. QT ubuntu下 多画面视频监控播放器rtsp播放器
  12. 计算机高配置表cpu,高配置电脑配置清单
  13. js根据文字获取首字母案例,直接复制在html中即可查看效果
  14. 机器翻译的概述(冰山一角)
  15. 计算机的英语怎样写,电脑的英文作文怎么写好呢
  16. 泊松分布 Poisson Distribution
  17. 好嗨哟,这5个超牛的资源网站,让你轻松无忧找资源!
  18. 【特征】PSI的计算
  19. Seastar Tutorial 简明教程
  20. 大数据知识图谱项目——基于知识图谱的医疗知识问答系统(详细讲解及源码)

热门文章

  1. php $path_info,PHP $_SERVER['PATH_INFO'] 无法获取到内容怎么办?
  2. php中html写法,细致说明注解三种PHP嵌套HTML的写法_后端开发
  3. 服务器用户配置文件在哪里找,SharePoint Server 中的服务器到服务器身份验证和用户配置文件...
  4. Hadoop架构中各个集群在开发中的作用
  5. 分类问题的评价及matrix , precision, recall
  6. java中调用 dll 动态库的简洁方法 JNative
  7. 如何在秋招中拿到offer?
  8. Spring Security 5.0.0正式发布
  9. [Erlang 0022] It solves the right problems in the right way at the right time
  10. CentOS 系统sudo命令配置