CWAC-SafeRoom – Room加密框架
前言
在这一期工作开发中涉及到敏感数据加密,现在数据存储用的MMKV
和Room
,MMKV
自带加密,Room
数据库怎么加密呢?之前没有数据加密相关的工作经验,对加密的了解只停留在书本上的对称加密、非对称加密上。所以首先想的是有没有加密工具类以及密钥如何获取,而且数据那么多,如何对数据进行统一的加密呢?带着这个疑问咨询了导师,导师让我预研下CWAC-SafeRoom
框架。
1、CWAC-SafeRoom框架概述
GitHub上对其描述是:CWAC-SafeRoom
实现了 Room 可用于处理特定版本的 SQLite 的一系列类和接口。具体来说,这个项目的类将Room与SQLCipher for Android连接起来,SQLCipher for Android是SQLite的一个版本,提供其内容的透明加密。
2、引入方式
官方提供了两种引入方式,一种是适用于AndroidX,另一种适用于老版的Android 支持库,这里我使用了第一种引入方式。
AndroidX
repositories {
maven {
url "https://s3.amazonaws.com/repo.commonsware.com"
}
}
dependencies {
implementation "com.commonsware.cwac:saferoom.x:1.3.0"
}
Android 支持库
repositories {
maven {
url "https://s3.amazonaws.com/repo.commonsware.com"
}
}
dependencies {
implementation "com.commonsware.cwac:saferoom:1.2.1"
}
3、用法
Room.databaseBuilder(
context,
AppDatabase::class.java, "database-market"
)
.build()
我们在实例化Room数据库中需要传入几个参数
context
– Java里的上下文class
– Room的dataBase类name
– 数据库保存之后的文件名称
填完参数,我们再写build()
来返回dataBase类的实体
使用 SafeRoom
- 创建加密实例将密码传递给SafeHelperFactory类
- 将加密实例添加在Room数据库实例化中
// 创建一个加密实例
val factory = SafeHelperFactory(AppConfig.DB_PASSWORD.toCharArray())
return Room.databaseBuilder(
context,
AppDatabase::class.java, "database-market"
)
.openHelperFactory(factory)
.build()
4、获取数据库状态
SQLCipherUtils
类中内置State
枚举类(检测到的数据库状态,基于我们是否可以在没有密码的情况下打开它),包含了数据库的三种状态,分别是
- DOES_NOT_EXIST — 不存在
- UNENCRYPTED — 未加密
- ENCRYPTED — 已加密
getDatabaseState()
方法通过传入context、数据库名称,返回该数据库的状态。其原理是来通过我们是否可以在没有密码的情况下打开它来确定此数据库是否显示为加密。
/**
* 获取数据库状态
*/
private fun checkDbState(): SQLCipherUtils.State {
return SQLCipherUtils.getDatabaseState(context, "database-market")
}
5、兼容处理
兼容处理是通过对数据库状态的判断,对未加密的数据库进行数据加密的一个操作。
/**
* 兼容处理
*/
private fun compatibleDb() {
when (checkDbState()) {
SQLCipherUtils.State.ENCRYPTED -> {
// 已加密 do nothing
}
SQLCipherUtils.State.UNENCRYPTED -> {
SQLCipherUtils.encrypt(
context,
"database-market",
AppConfig.DB_PASSWORD.toCharArray()
)
}
SQLCipherUtils.State.DOES_NOT_EXIST -> {
SpeedyLog.e(MdmConstant.BaseTAG, "数据库不存在")
}
}
}
6、更改加密密钥
可以通过SafeHelperFactory
类中的rekey()
方法更改与此数据库关联的密码。需要传入数据库和char[]类型的密码。需要注意的是加密更改不适用于未加密的数据库,所以在更改密钥前需要对未加密的数据库进行处理。
/**
* 更改加密密钥
* 加密更改不适用于未加密的数据库
* @param dataBase
* @param pass
*/
fun reKey(dataBase: SupportSQLiteDatabase, pass: CharArray) {
launchScope.launch {
//将未加密的数据库进行处理
compatibleDb()
SafeHelperFactory.rekey(dataBase, pass)
}
}
7、实现效果
在Android Studio
– App Inspection
– Database Inspector
中查看
无加密框架效果
有加密框架效果
8、性能测试
对两个数据库插入数据消耗的时间进行统计,得出CWAC-SafeRoom
框架对性能的影响还是比较大的。
9、小结
在开发过程中,学习到了Room的加密框架,CWAC-SafeRoom
框架学习使用起来还是较为容易的。本文只列举了其中较为常用的方法,想要了解更多的话,可以查看GitHub上的项目,网址放在下方了。文章若出现错误,欢迎各位批评指正,写文不易,转载请注明出处谢谢。
GitHub项目网址:
详情可以参考README-original.markdown
文档中的框架概述和具体使用操作
CWAC-SafeRoom加密框架