Android数据库安全解决方案,使用SQLCipher进行加解密
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952409
我们都知道,Android系统内置了SQLite数据库,并且提供了一整套的API用于对数据库进行增删改查操作。数据库存储是我们经常会使用到的一种存储方式,相信大多数朋友对它的使用方法都已经比较熟悉了吧。在Android中,我们既可以使用原生的SQL语句来对数据进行操作,也可以使用Android API提供的CRUD方法来对数据库进行操作,两种方式各有特点,选择使用哪一种就全凭个人喜好了。
不过,使用SQLite来存储数据却存在着一个问题。因为大多数的Android手机都是Root过的,而Root过的手机都可以进入到/data/data/<package_name>/databases目录下面,在这里就可以查看到数据库中存储的所有数据。如果是一般的数据还好,但是当涉及到一些账号密码,或者聊天内容的时候,我们的程序就会面临严重的安全漏洞隐患。那么今天,就让我们一起研究一下如何借助SQLCipher来解决这个安全性问题。
SQLCipher是一个在SQLite基础之上进行扩展的开源数据库,它主要是在SQLite的基础之上增加了数据加密功能,如果我们在项目中使用它来存储数据的话,就可以大大提高程序的安全性。SQLCipher支持很多种不同的平台,这里我们要学习的自然是Android中SQLCipher的用法了。
下面我们就开始吧,首先要把Android项目所依赖的SQLCipher工具包下载下来,下载地址是:
https://s3.amazonaws.com/sqlcipher/SQLCipher+for+Android+v2.2.2.zip
接着解压这个工具包,会看到里面有assets和libs这两个目录,稍后需要将这两个目录中的内容添加到Android项目当中。那么现在我们就来新建一个Android项目,项目名就叫SQLCipherTest。
观察SQLCipherTest的项目结构,发现里面也分别有一个assets目录和一个libs目录,那么现在就可以把SQLCipher工具包中这两个目录里的内容复制过来。并不需要复制全部文件,选择必要的文件进行复制就可以了,完成以后项目结构图如下所示,图中显示的文件都是必要的。
到这里准备工作就全部完成了,接下来我们开始编写代码。首先创建一个MyDatabaseHelper继承自SQLiteOpenHelper,注意这里使用的并不是Android API中的SQLiteOpenHelper,而是net.sqlcipher.database包下的SQLiteOpenHelper,代码如下所示:
import android.content.Context;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabase.CursorFactory;
import net.sqlcipher.database.SQLiteOpenHelper; public class MyDatabaseHelper extends SQLiteOpenHelper { public static final String CREATE_TABLE = "create table Book(name text, pages integer)"; public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
} @Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
} @Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) { } }
除了引入的包不一样了,其它的用法和传统的SQLiteOpenHelper都是完全相同的。可以看到,我们在onCreate()方法中创建了一张Book表,Book表里有name和pages这两个列。
接着,打开或新建activity_main.xml作为程序的主布局文件,代码如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <Button
android:id="@+id/add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加数据"
/> <Button
android:id="@+id/query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询数据"
/> </LinearLayout>
这里只是简单地放置了两个按钮,分别用于添加和查询数据。接下来打开或新建MainActivity作为程序主Activity,代码如下所示:
public class MainActivity extends Activity {
private SQLiteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SQLiteDatabase.loadLibs(this);
MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "demo.db", null, 1);
db = dbHelper.getWritableDatabase("secret_key");
Button addData = (Button) findViewById(R.id.add_data);
Button queryData = (Button) findViewById(R.id.query_data);
addData.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put("name", "达芬奇密码");
values.put("pages", 566);
db.insert("Book", null, values);
}
});
queryData.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Cursor cursor = db.query("Book", null, null, null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
Log.d("TAG", "book name is " + name);
Log.d("TAG", "book pages is " + pages);
}
}
cursor.close();
}
});
}
}
可以看到,在onCreate()方法中首先调用了SQLiteDatabase的loadLibs()静态方法将SQLCipher所依赖的so库加载进来,注意这里使用的是net.sqlcipher.database包下的SQLiteDatabase。然后我们创建了MyDatabaseHelper的实例,并调用getWritableDatabase()方法去获取SQLiteDatabase对象。这里在调用getWritableDatabase()方法的时候传入了一个字符串参数,它就是SQLCipher所依赖的key,在对数据库进行加解密的时候SQLCipher都将使用这里指定的key。
在添加数据按钮的点击事件里面,我们通过ContentValues构建了一条数据,然后调用SQLiteDatabase的insert()方法将这条数据插入到Book表中。
在查询数据按钮的点击事件里面,我们调用SQLiteDatabase的query()方法来查询Book表中的数据,查询到的结果会存放在Cursor对象中,注意这里使用的是net.sqlcipher包下的Cursor。然后对Cursor对象进行遍历,并将查询到的结果打印出来。
现在运行一下程序,先点击添加数据按钮,再点击查询数据按钮,刚刚添加的那条数据就应该在控制台里打印出来了。
有没有感觉到使用SQLCipher提供的API和使用Android原生的数据库API,操作起来几乎是一模一样的。没错,SQLCipher对Android SDK中所有与数据库相关的API都制作了一份镜像,使得开发者可以像操作普遍的数据库文件一样来操作SQLCipher,而所有的数据加解密操作,SQLCipher都在背后帮我们处理好了。
话说写到这里,我们都一直还没体验一下SQLCipher加密后的效果呢,现在就来看一看吧,首先通过命令行的方式来访问demo.db这个数据库文件:
adb shell
cd /data/data/com.example.sqlciphertest/databases
sqlite3 -line demo.db
.table
尝试查看demo.db中的所有表,结果返回如下图所示:
从图中可以看出,当执行.table命令的时候被拒绝了,原因是数据库文件已加密。
除了使用命令行的方式,我们还可以尝试使用Root Explorer来打开数据库文件,结果如下图所示:
意料之中,果然打开失败了。这就足以说明,目前数据库中的数据是非常安全的,只有在应用程序里通过SQLCipher提供的API才可以访问到数据库里的数据,使用其它的方式都无法获取其数据。
需要提醒的一点是,项目中引入了SQLCipher之后,会让你的程序体积骤然增加,打成APK后大概会变大好几M,是更侧重于文件大小,还是更侧重于程序安全,你应该根据具体的需求做出合适的判断。
好了,今天的讲解到此结束,有疑问的朋友请在下面留言。
Android数据库安全解决方案,使用SQLCipher进行加解密的更多相关文章
- android中使用jni对字符串加解密实现分析
android中使用jni对字符串加解密实现分析 近期项目有个需求.就是要对用户的敏感信息进行加密处理,比方用户的账户password,手机号等私密信息.在java中,就对字符串的加解密我们能够使用A ...
- QuickBase64 - Android 下拉通知栏快捷base64加解密工具
Android Quick Setting Tile Base64 Encode/Decode Tool Android 下拉通知栏快捷 base64 加解密,自动将剪切板的内容进行 base64 E ...
- Android数据库安全解决方案,使用SQLCipher
源码:http://files.cnblogs.com/android100/SQLCipherTest.rar 我们都知道,Android系统内置了SQLite数据库,并且提供了一整套的API用于对 ...
- 【iOS】FMDB/SQLCipher数据库加解密,迁移
2016-04-19更新:本文代码可能有些问题,请移步 http://zhengbomo.github.io/2016-04-18/sqlcipher-start/ 查看 sqlite应用几乎在所有的 ...
- 彻底告别加解密模块代码拷贝-JCE核心Cpiher详解
前提 javax.crypto.Cipher,翻译为密码,其实叫做密码器更加合适.Cipher是JCA(Java Cryptographic Extension,Java加密扩展)的核心,提供基于多种 ...
- MD5+DES在C#.NET与Java/Android中的加解密使用
一.背景后台(C#.NET)使用一个MD5+DES的加解密算法,查了下,很多网友都使用了这个算法.在Android里,也需要这个算法,如何把这个加解密算法切换成Java版,成了难题.毕竟好久没涉及到这 ...
- AES加解密算法在Android中的应用及Android4.2以上版本调用问题
from://http://blog.csdn.net/xinzheng_wang/article/details/9159969 AES加解密算法在Android中的应用及Android4.2以上 ...
- DES跨(C# Android IOS)三个平台通用的加解密方法
#region 跨平台加解密(c# 安卓 IOS) // public static string sKey = "12345678"; ...
- Android中加解密算法大全
Base64编码 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,本质上是一种将二进制数据转成文本数据的方案,对于非二进制数据,是先将其转换成二进制形式,然后每连续6比特(2的6次 ...
随机推荐
- Windows 10设置桌面图标间距、窗口的背景颜色、选中文字的背景颜色
Windows 10取消了“高级外观设置”(或者叫“窗口颜色和外观”设置),想调整一些参数只能进注册表了. 修改后可能需要注销或重启才能生效. 按Win+R,然后输入regedit进入注册表编辑器. ...
- LeetCode Bulb Switcher 319
变换灯泡颜色 There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off ...
- matlab图
.6 统计作图 4.6.1 正整数的频率表 命令 正整数的频率表 函数 tabulate 格式 table = tabulate(X) %X为正整数构成的向量,返回3列:第1列中包含X的值第2列为这些 ...
- Centos apache + mysql + usvn 配置svn 服务器
1.遇到问题 提交异常:'svn/!svn/me'path not found http://www.myexception.cn/cvs-svn/1262826.html 更改http.conf 配 ...
- -[UIKeyboardLayoutStar release]: message sent to deallocated instance 0x7fbe49120000
__NSArrayM objectAtIndex: 取消swizzle 只有debug的时候会报错,发布的时候是好的,所以可以不用改
- 2016国内最值得期待的响应式前端框架pintuer(拼图)--http://www.pintuer.com
近期,需要将项目从pc端的应用扩展到移动端. 当然移动框架的第一选择必然是bootstrap,但是bootstrap作为移动端明显过于死板,而且作为国外的产品,对于国内的应用明显水土不服.框架里总有那 ...
- CocoaPod安装和使用教程
一.CocoaPods是什么? CocoaPods是一个负责管理iOS项目中第三方开源库的工具.CocoaPods的项目源码在Github上管理.我们开发iOS项目不可避免地要使用第三方开源库,Coc ...
- mysql计划字段中有多少个逗号,或者某个标识符
eg:计划url中有多少个小数点 select length('www.mysql.com')-length(REPLACE('www.mysql.com','.',''));
- HR常用事务代码
HR TCODE 描述 PA30 维护人力资源主数据 PA40 人事活动
- MyElipes遇到 source not found解决方案(查看.class文件源码一劳永逸的解决方法)
在用Myeclipse 或者是eclipse进行开发时候经常遇到这个问题. File class editor source not found 问题.原因很简单,就是因为这是一个源码包,相应的没有编 ...