DataStore存储数据+加上加密

如果没有使用SP来存储数据,而是用datastore的话

但是datastore存储是个文件,所以我们需要再加密。

先展示没有加密的存储方式,然后再结合上一节的加密,再将存储的数据进行加密

使用datastore存储数据

添加依赖库

implementation "androidx.datastore:datastore-preferences:1.0.0"
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2'

定义数据类型

定义data class,添加 @Serializable 标签

@Serializable
data class UserSettings(
    val username: String? = null,
    val password: String? = null
)

定义Serializer

这里先展示没有加密的的序列化

存储的时候,将实例值转换成json string,再转换成bytearray写出到输出流,就可以保存到datastore的文件上了

读取的时候,从输入流中读取转成json string, 再通过json解析成 UserSetting实例

//继承datastore的Serializer,类型是我们定义的UserSettings
@RequiresApi(Build.VERSION_CODES.M)
class UserSettingsSerializer() : Serializer<UserSettings> {

    override val defaultValue: UserSettings
        get() = UserSettings()

    override suspend fun readFrom(input: InputStream): UserSettings {
        //将输入端的内容先转换成string
        //再将string通过json的解析再转换成UserSettings
        return try {
            Json.decodeFromString(
                deserializer = UserSettings.serializer(),
                string = inputStreamToByteArray(input).decodeToString()//decryptedBytes.decodeToString()
            )
        } catch(e: SerializationException) {
            e.printStackTrace()
            defaultValue
        }
    }

    private fun inputStreamToByteArray(inputStream: InputStream): ByteArray {
        val dataInputStream = DataInputStream(inputStream)
        val byteArrayOutputStream = ByteArrayOutputStream()

        val buffer = ByteArray(1024)
        var length: Int
        while ((dataInputStream.read(buffer).also { length = it }) != -1) {
            byteArrayOutputStream.write(buffer, 0, length)
        }

        return byteArrayOutputStream.toByteArray()
    }

    override suspend fun writeTo(t: UserSettings, output: OutputStream) {
        //把值为t的UserSettings,通过序列化转换成json string,再写出到输出流
        val bytes =Json.encodeToString(serializer=UserSettings.serializer(), value = t)
            .encodeToByteArray()
        output.write(bytes)

    }
}

初始化datastroe

datastore的文件名,传入我们前面定义的普通的序列化器UserSettingsSerializer,

定义的是Context.dataStore,这在Context中都可以访问到datastore。例如activity中就可以直接使用datastore

 private val Context.dataStore by dataStore(
        fileName = "user-settings.json",
        serializer = UserSettingsSerializer()
    )

跟新数据到datastore

                                dataStore.updateData {
                                    UserSettings(
                                        username = username,
                                        password = password
                                    )
                                }

读取数据

settings = dataStore.data.first()

直接就可以读取到 UserSetting类型的数据

查看文件

从data-data-packagename下可以看到文件

直接可以看到JSON格式的内容,这样就不是很安全,所以,存储到datastore中的内容需要加密

这个就连接上一篇中的AES加密

https://blog.youkuaiyun.com/github_35581409/article/details/142894715

只要对UserSettingsSerializer进行改造,在写入的时候,把JSON string进行加密

在读取的时候,先对string解密,然后再JSON解析

加密改造

添加加密管理

class UserSettingsSerializer(
    private val cryptoManager: CryptoManager //添加加密管理
) : Serializer<UserSettings>

写入

写入的时候,将实例值通过json编码,然后转换成byte。然后再通过cryptoManager进行加密,再写入输出流,输出流会把加密后的数据存储到datastore的文件中

    override suspend fun writeTo(t: UserSettings, output: OutputStream) {
        cryptoManager.encrypt(
            bytes = Json.encodeToString(
                serializer = UserSettings.serializer(),
                value = t
            ).encodeToByteArray(),
            outputStream = output
        )
//        val bytes =Json.encodeToString(serializer=UserSettings.serializer(), value = t)
//            .encodeToByteArray()
//        output.write(bytes)

    }

读取

把输入流中的内容,先进行解码,解码后的byte,在通过json组装成实例

    override suspend fun readFrom(input: InputStream): UserSettings {
        val decryptedBytes = cryptoManager.decrypt(input) //将输入流进行加密,生成加密后的bytes
        return try {
            Json.decodeFromString(
                deserializer = UserSettings.serializer(),
//                string = inputStreamToByteArray(input).decodeToString()
                decryptedBytes.decodeToString()
            )
        } catch(e: SerializationException) {
            e.printStackTrace()
            defaultValue
        }
    }

在datastore初始化的时候,补上加密管理器

   private val Context.dataStore by dataStore(
        fileName = "user-settings.json",
        serializer =UserSettingsSerializer(CryptoManager())
    )

再运行看看,加解密显示没有问题,

文件内容也变成了加密的了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值