Android SQLite数据库加密的操作方法

一、前言

SQLite是一个轻量级的、跨平台的、开源的嵌入式数据库引擎,也是一个关系型的的使用SQL语句的数据库引擎,
读写效率高、资源消耗总量少、延迟时间少,使其成为移动平台数据库的最佳解决方案(如Android、iOS)
但是Android上自带的SQLite数据库是没有实现加密的,我们可以通过Android Studio直接导出应用创建的数据库文件,然后通过如SQLite Expere Personal 这种可视化工具打开数据库文件进行查看数据库的表结构,以及数据,这就导致存储在SQLite中的数据可以被任何人查看,如果是一些账号密码,或者聊天数据等,那么我们的应用就面临着严重的安全漏洞隐患;

二、数据库加密方法

因为Android自带的SQLite数据库本身是没有实现加密的,那我们如何实现对数据库的加密呢?

(1)对SQLite数据库的数据进行加密

我们可以在程序中对保存到数据库中的数据 进行加密后保存,然后查询数据的时候,对查询的数据进行解密后使用,如果还不希望别人看到数据库的表结构,我们可以对数据库名字,表名,表中的字段名字使用MD5等加密手段加密后再进行操作;
这种方法是可以达到数据库加密的目的的,但是相对来说操作就比较繁琐了

(2)使用SQLCipher对SQLite数据库加密

SQLCipher是基于SQLite基础之上实现了数据库加密的开源库,可以采用第三方的开源框架SQLCipher,SQLCipher是基于原生SQlite数据库进行扩展,实现数据库整体加密(数据库文件加密),提供的数据库的操作接口,和原生的SQLite数据库操作接口基本一样的;我们创建或者打开数据库都需要密码,我们打开数据库时的密码,需要和创建数据库时的密码保护一致,否则打开数据库时会报错,提示打开的文件不是一个数据库文件

net.sqlcipher.database.SQLiteException: file is not a database;

我们导出的数据库文件,通过SQLite Expere Personal这类可视化工具也是无法直接打开的;但是可以使用DB Browser for Sqlite这个数据库查看工具进行查看,查看的时候输入创建数据库时使用的加密密码

SQLCipher的特点:

SQLCipher 占用空间小,性能好,因此非常适合保护嵌入式应用程序数据库,非常适合移动开发。

(1)极快的性能,加密开销低至 5-15%

(2)数据库文件中的数据 100% 已加密,是对所有数据文件,包括数据文件和缓存、结构文件等等进行加密。

(3)使用良好的安全实践(CBC 模式、密钥派生),加密算法是256位 AES 在 CBC 模式

(4)使用 OpenSSL 加密库提供的算法

在Android中集成SQLiteCipher:

-添加SQLiteCipher的依赖

implementation 'net.zetetic:android-database-sqlcipher:4.4.3@aar'
implementation "androidx.sqlite:sqlite:2.0.1"

-使用SQLiteCipher提供的相关接口操作

 SQLiteDatabase.loadLibs(this)
                val databaseFile = getDatabasePath("demo.db")
                if (databaseFile.exists()) databaseFile.delete()
                databaseFile.mkdirs()
                databaseFile.delete()
                val database = SQLiteDatabase.openOrCreateDatabase(databaseFile, "test123", null)
                database.execSQL(
                    "CREATE TABLE " + DatabaseHelper.TABLE_MUSIC_TYPE + " (type_id integer primary key autoincrement not null," +
                            "type_no integer,type_name text)"
                )
                database.execSQL(
                    "insert into " + DatabaseHelper.TABLE_MUSIC_TYPE + " (type_no,type_name) " +
                            "values ('" + 1 + "','" + "送餐音乐" + "')"
                )

上面的代码在调用时,会创建数据库demo.db,传入了数据库密码,并且创建了一个表music_type,并且向表中插入了一条数据;
注意代码中的数据库相关的操作,都是使用SQLIteCipher中的相关接口即net.sqlcipher.database包名下的相关接口,不要使用成了原生SQLite的相关接口

SQLiteDatabase.loadLibs(this)
                val databaseFile = getDatabasePath("demo.db")
                val database = SQLiteDatabase.openOrCreateDatabase(databaseFile, "test123", null)
                val cursor = database.rawQuery(
                    "select * from " + DatabaseHelper.TABLE_MUSIC_TYPE,
                    null
                )

                var musicTypeList: MutableList<MusicTypeBean> = mutableListOf();

                while (cursor.moveToNext()) {
                    var musicTypeBean = MusicTypeBean();
                    musicTypeBean.id = cursor.getInt(cursor.getColumnIndex("type_no"))
                    musicTypeBean.name = cursor.getString(cursor.getColumnIndex("type_name"))
                    musicTypeList.add(musicTypeBean)
                }
                cursor.close()
                Log.e(TAG, "onClick: " + musicTypeList.size)

上述代码就是查询demo.db数据库中的music_type表中的数据,获取数据库对象的时候,注意传入的密码和创建数据库时要保持一致;

上面使用SQLiteCipher创建数据库和表,以及向表中插入数据,查询表中的数据,除了创建数据库获取可读写数据库对象和原生SQLite API有些区别一样,其他执行SQL语句,查询表中数据的API 和原生 SQlite API是完全一样的;

SQLiteCipher结合Room框架使用

我们知道在使用SQLite数据库的时候,我们往往会使用一些比较方便的ORM(对象关系映射)框架来帮助我们操作数据库,如GreenDAO,Room(Jetpack组件)等,那如何将SQLiteCipher结合这些ORM框架使用;我们这里介绍一下Google Jetpack组件中的ORM框架 Room结合SQLiteCipher使用;

其实Room结合SQLiteCipher使用,就是在创建数据库时候,需要先创建一个SupportFactory
,SupportFactory中会传入通过SQLiteCipher中的SQLiteDatabase获取的密码字节数据

  SQLiteDatabase.loadLibs(this)
                val passphrase = SQLiteDatabase.getBytes("test123".toCharArray())
                val factory = SupportFactory(passphrase, object : SQLiteDatabaseHook {
                    override fun preKey(database: SQLiteDatabase?) {
                        LogUtil.e(TAG, "preKey")
                    }

                    override fun postKey(database: SQLiteDatabase?) {
                        LogUtil.e(TAG, "postKey")
                    }
                }, true)

然后在创建数据库的时候,通过Room自带的openHelperFactory()方法传入创建的SupportFactory即可,这样就能创建加密数据库了;其他操作,就按照Room正常的操作即可

var mInstance= Room
                   .databaseBuilder(
                            context.applicationContext,
                            AppDatabase::class.java,
                            DB_NAME
                        ).addCallback(object : RoomDatabase.Callback() {
                            override fun onCreate(db: SupportSQLiteDatabase) {
                                super.onCreate(db)
                                Log.e(TAG, "onCreate: ")
                                initMusicTypeData(context, db)
                            }
                        }).openHelperFactory(factory)
                        .build()

查看并导出加密数据库文件

-导出数据库文件

我们手机通过USB连接电脑之后,打开开发者模式,然后在Android Studio菜单栏中的View->
Tool Windows->Device File Explorer

然后在Device File Explorer中进入 data/data/应用包名/databases中找到我们创建的数据库文件demo.db,然后我们可以右键改文件Save As 导出该数据库文件


-查看加密数据库文件

前面我们已经提到过,可以通过DB Browser for SQLite来查看加密的数据库文件
下载地址:https://sqlitebrowser.org/dl/

下载安装之后,我们打开安装目录下的DB Browser for SQLCipher.exe程序,然后通过菜单栏中的文件->打开数据库->打开导出的加密数据库文件,然后输入数据库文件的加密密码,就是我们在程序中SQLiteCipher加密数据库文件时使用的密码,输入正确密码后,可以正常打开数据库文件


右键表名,选择浏览数据,即可查看表中的数据

到此这篇关于Android SQLite数据库加密的操作方法的文章就介绍到这了,更多相关Android SQLite数据库加密内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解Android数据存储之SQLCipher数据库加密

    前言: 最近研究了Android Sqlite数据库以及ContentProvider程序间数据共享,我们清晰的知道Sqlite数据库默认存放位置data/data/pakage/database目录下,对于已经ROOT的手机来说的没有任何安全性可以,一旦被利用将会导致数据库数据的泄漏,所以我们该如何避免这种事情的发生呢?我们尝试这对数据库进行加密. 选择加密方案: 1.)第一种方案 我们可以对数据的数据库名,表名,列名就行md5,对存储的数据进行加密,例如进行aes加密(Android数据加密

  • Android中的sqlite查询数据时去掉重复值的方法实例

    1.方式一: /** * 参数一:是否去重 * 参数二:表名 * 参数三:columns 表示查询的字段,new String[]{MODEL}表示查询该表当中的模式(也表示查询的结果) * 参数思:selection表示查询的条件,PHONE_NUMBER+" = ?" 表示根据手机号去查询模式 * 参数五:selectionArgs 表示查询条件对应的值,new String[]{phoneNumber}表示查询条件对应的值 * 参数六:String groupBy 分组 * 参数

  • android 中 SQLiteOpenHelper的封装使用详解

    在android中常用存储数据的基本就三种,sqlite,SharedPreferences,文件存储,其中针对于对象存储,使用sqlite比较多,因为可以对其进行增删改查.本文主要讲解SQLiteOpenHelper的封装使用,代码引用自https://github.com/iMeiji/Toutiao 具体使用 主要方法包括创建数据库和数据库的升级. 构造函数:包含三个参数,context,name,factory,version onCreate:主要创建了三张表单 getDatabase

  • Android Studio 通过登录功能介绍SQLite数据库的使用流程

    前言: SQLite简介:是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了.它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl.C#.PHP.Java等,还有ODBC接口,同样比起Mysql.PostgreSQL这两款开源的世

  • Android SQLite数据库加密的操作方法

    一.前言 SQLite是一个轻量级的.跨平台的.开源的嵌入式数据库引擎,也是一个关系型的的使用SQL语句的数据库引擎, 读写效率高.资源消耗总量少.延迟时间少,使其成为移动平台数据库的最佳解决方案(如Android.iOS) 但是Android上自带的SQLite数据库是没有实现加密的,我们可以通过Android Studio直接导出应用创建的数据库文件,然后通过如SQLite Expere Personal 这种可视化工具打开数据库文件进行查看数据库的表结构,以及数据,这就导致存储在SQLit

  • Android SQLite数据库版本升级的管理实现

    Android SQLite数据库版本升级的管理实现 我们知道在SQLiteOpenHelper的构造方法: super(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) 中最后一个参数表示数据库的版本号.当新的版本号大于当前的version时会调用方法: onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 所以我们

  • Android SQLite数据库中的表详解

    Android SQLite数据库 前言 以前写PHP的时候,内置了print_r()和var_dump()两个函数用于打印输出任意类型的数据内部结构,现在做Android的开发,发现并没有这种类似的函数,对于数据库的查看很不方便,于是就写了一下查看数据库表的方法代码. 代码实现 import java.util.Arrays; import android.app.Activity; import android.database.Cursor; import android.database

  • Android SQLite数据库的增 删 查找操作

    在Android开发中,有时我们需要对SQLite数据库进行增,删,查,找等操作,现在就来简单介绍一下,以下为详细代码. 一.创建一个自定义数据库 二.创建一个自定义适配器 三.编写MainActivity代码 以上所述是小编给大家介绍的Android SQLite数据库的增 删 查找操作,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的.在此也非常感谢大家对我们网站的支持!

  • Android+SQLite数据库实现的生词记事本功能实例

    本文实例讲述了Android+SQLite数据库实现的生词记事本功能.分享给大家供大家参考,具体如下: 主activity命名为 Dict: 代码如下: package example.com.myapplication; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase;

  • Android SQLite数据库基本操作方法

    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能.而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库.那么就来看一下在Android程序中怎么去操作SQLite数据库来实现一些需求的吧,仍然以一个小例子开始: 在创建Android项目之前,我们应该想一下我们要定义的数据库的相关信息和里面的表格的相关信息,为了日后数据库的更新更加方便 ,我们可以用一个专门的类保存数据库的相关信息,以后如果要更新数据库的话只需要该动这个类

  • Android SQLite数据库增删改查操作的使用详解

    一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NULL.INTEGER.REAL(浮点数字). TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n). char(n).decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型. SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段

  • Android SQLite数据库彻底掌握数据存储

    SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值. 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误. 另外, SQLite 在解析CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句

  • Android Room数据库加密详解

    本文实例为大家分享了Android Room之数据库加密的具体实现,供大家参考,具体内容如下 一.需求背景 Android平台自带的SQLite有一个致命的缺陷:不支持加密.这就导致存储在SQLite中的数据可以被任何人用任何文本编辑器查看到.如果是普通的数据还好,但是当涉及到一些账号密码,或者聊天内容的时候,我们的应用就会面临严重的安全漏洞隐患. 二.加密方案 1.在数据存储之前进行加密,在加载数据之后再进行解密,这种方法大概是最容易想的到,而且也不能说这种方式不好,就是有些比较繁琐. 如果项

  • Android  SQLite数据库彻底掌握数据存储

    SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值. 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误. 另外, SQLite 在解析CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句

随机推荐