本文整理自网络,侵删。
一、前言
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表中的数据,获取数据库对象的时候,注意传入的密码和创建数据库时要保持一致;
相关阅读 >>
android 中自定义contentprovider与contentobserver的使用简单实例
database.net强大的数据库查询管理工具使用图文教程
scrapy+scrapyd+gerapy爬虫调度框架超详细教程
android studio连接Sqlite数据库的登录注册实现
更多相关阅读请进入《Sqlite》频道 >>
数据库系统概念 第6版
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。