使用Jetpack-Security库加密SharedPreferences

本文介绍 Jetpack-Security 库的使用,安全地管理密钥并对文件和 SharedPreferences 进行加密。(注:仅支持 minSdkVersion 23+

SharedPreferences 是一个用于存储小量键值数据很好的工具,但当存储一些敏感数据时,SharedPreferences 存储的键值数据是明文的,对于敏感数据,我们应该进行加密,所以我们一般有几种做法:

  1. 使用 Android 密钥库自己写加密来包装 SharedPreferences
  2. 使用第三方库,封装的SharedPreferences

以上都不是很靠谱的做法,现在 Jetpack-Security 库的出现,让 SharedPreferences 存储加密更容易和方便,但仅支持 minSdkVersion 23+

使用

在应用或模块的 build.gradle 文件中添加所需工件的依赖项:

dependencies {
    implementation "androidx.security:security-crypto:1.0.0"
}

在添加了依赖之后,我们要进行在 Android KeyStore 创建一个加密 master key 和 store。

val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

在这里我们指定了一个默认的 key,AES256_GCM_SPEC,用来创建 master key。

最后我们需要创建 EncryptedSharedPreferences,它对 SharedPreferences 进行了包装并且会为我们处理所有的加密。

const val FILE_NAME = "app_share"

EncryptedSharedPreferences.create(
FILE_NAME,
masterKeyAlias,
context,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

在创建中我们制定了 SharedPreferences 的文件名,创建的 masterKeyAlias ,以及context。后面的两个参数是 key 和 value 加密的 scheme,它们是库提供的选项。

在创建了 EncryptedSharedPreferences 实例后,我们可以正常使用 SharedPreferences 读取和存储,最终代码如下:

val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

const val FILE_NAME = "app_share"

val sp = EncryptedSharedPreferences.create(
FILE_NAME,
masterKeyAlias,
context,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

// save a value
sp.edit().putString("sp_key","data").apply()

// read a value
sp.getString("sp_key","defalut")

校验数据

我们去检查下数据是否被加密了,一般 SharedPreferences 的文件数据在 /data/data/{packageName}/shared_prefs/{SharedPreferences文件名}

正常的 SharedPreferences,文件内容如下:



    data


在使用了 EncryptedSharedPreferences 加密过后,文件内容如下:



    12a901ef1070f09bff3ce84e02def76f45b4a7b83f9700d97dba0bcd7d4555c777df36417605da8c00609c2e563f496b91f89a126e3ecf5623ea25f5d051bd44bbff3a7f5fd8654e6570b2e568b08e46f8fcefce2161ceebf9808425dbc30fa42035bd59ddf1de49482034bccf3c7198888b857389ee8b5f12104b3306c271fc85770cf3f5db70a5215213d07840adb86ee73ccc96ad7069ddf22cedc55674d94d719628ba5982c4aa8357381a4408b8c88a9403123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118b8c88a94032001
    ATvCdd9NsncgS7HDfM3baFgwRvAYOrdzAZwaXD1I0mRjI31WsbVvi5E=
    12880176be20810bda48152c5a724c2e1653b60e9c66bfd7a4be40c9d3a1073e3efd2572a77373ed1b71c2fdaf586c1aeeb39eb230b906ffb2d69cecf820916b7a1c6e6f0c532274e045c924f674bb3437103fa914a0219c72c4ef23750398aef93dcfd0945d78d4ee8e8efbcab7a317234458836c32709516479179b4cf0401187d823f5caeeb487678521a4408dfeb89de03123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118dfeb89de032001


我们可以看到 key 和 value 被加密了并且存储了两个 keyset ,分别是 加密的 key 和 value 。

结语

Jetpack-Security 库对于 SharedPreferences 的数据加密是很有用的工具,对于敏感数据,这是一个很好的加密方法,但仅支持minSdkVersion 23+,虽然现在大多是高版本系统的设备,对于低端设备的兼容就很难受了,所以还是可以尝试去用。

你可能感兴趣的:(使用Jetpack-Security库加密SharedPreferences)