这里多次一举是为了巩固学习一下;
简介
好处:
- 提升开发效率:组件可以单独采用,同时利用Kotlin语言功能帮助你提升工作效率;
- 消除样板代码:Android Jetpack可管理繁琐的Activity(入后台任务、导航、生命周期管理),便于你专注于如何让自己的应用出类拔萃;
- 构建高质量的强大应用:围绕现代化设计实践构建而成,具有向后兼容性,可以减少崩溃和内存泄漏等问题;
Jetpack组件集合:
- 基础:Android KTX、 AppCompat、Auto、检测、多dex处理、安全、测试、TV等;
- 架构:数据绑定、Lifecycles(管理您的Activity Fragment生命周期)、LiveData、Navigation、Paging、Room、ViewModel、WorkManager(管理Andorid后台作业)
- 行为:Camerax(轻松向应用中添加相机功能)、下载管理器、媒体和播放、通知、权限、偏好设置、共享、切片
- 界面:动画和过渡、表情符号 、Fragment、布局、调色板
下面我们只会介绍几个我们常用的组件,没有介绍到的可以到官网查看
一、使用Jetpack Security为数据加密
Jetpack Security 是 Google I/O 2019 发布的安全组件库。Security构成简单,主要包含EncryptedFile
和EncryptedSharedPreferences
两个类,分别用来对File
和SharedPreferences
的读写进行加密解密处理。Security要求min SDK version 23。
image.png记住:加密处理的性能肯定比普通为加密的存在劣势;
1. EncryptedFile
封装了Google的加密库tink的逻辑,提供FileInputStream和FileOutputStream,可以更安全的进行流的读写。
2.EncryptedSharedPreferences
是SharedPreferences包装类,通过两种方式自动加密键/值:
- Key加密使用的是确定性的加密算法,使得秘钥可以被加密
- Value加密使用AES-256 GCM加密,不确定加密
秘钥管理
Security库秘钥管理分为两个部分:
- 秘钥集合: 包含一个或多个秘钥来加密文件或SharedPreferences数据,存储在SharedPreferences中。
- 主密钥: 用来加密所有秘钥集合,存储在Android Keystore系统中
使用Android Keystore的包装类MasterKeys只用两行就可以制作Master Key。
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
SharedPreferences加密例子:
使用EncryptedSharedPreferences
key和value被加密保存
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
val sharedPreferences = EncryptedSharedPreferences
.create(
"Sample",
masterKeyAlias,
context,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
val editor = sharedPreferences.edit()
editor.putInt("IntSave", 10)
editor.apply()
val intSaved = sharedPreferences.getInt("IntSave", 1)
Log.d("IntSave", intSaved.toString())
File文件加密例子:
例如向text文件中中写入 ”MY SUPER SECRET INFORMATION“字符串
写入:
val fileToWrite = "my_other_sensitive_data.txt"
val encryptedFile = EncryptedFile.Builder(
File(context.getFilesDir(), fileToWrite),
context,
masterKeyAlias,
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()
// 写入文件
try {
val outputStream: FileOutputStream? = encryptedFile.openFileOutput()
outputStream?.apply {
write("MY SUPER SECRET INFORMATION"
.toByteArray(Charset.forName("UTF-8")))
flush()
close()
}
} catch (ex: IOException) {
// Error occurred opening file for writing.
}
读取:
val fileToRead = "my_sensitive_data.txt"
lateinit var byteStream: ByteArrayOutputStream
val encryptedFile = EncryptedFile.Builder(
File(context.getFilesDir(), fileToRead),
context,
masterKeyAlias,
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()
try {
encryptedFile.openFileInput().use { fileInputStream ->
try {
val sb = StringBuilder()
val br = BufferedReader(InputStreamReader(fileInputStream) as Reader?)
br.readLine()
.forEach {
sb.append(it)
}
br.close()
// 输出 MY SUPER SECRET INFORMATION
Log.d("fileContents", sb.toString())
} catch (ex: Exception) {
// Error occurred opening raw file for reading.
} finally {
fileInputStream.close()
}
}
} catch (ex: IOException) {
// Error occurred opening encrypted file for reading.
}
网友评论