当前位置: 首页 > 知识库问答 >
问题:

Android API 21创建自定义主密钥

有翰海
2023-03-14

我试图创建一个加密的SharedReferences实现,但Android网站中给出的示例适用于API 23及以上版本。具体来说,问题是使用以下代码创建主密钥:MasterKeys。getOrCreate(MasterKeys.AES256\u GCM\u SPEC)

在当前版本的androidx Security('androidx.security: security-crypto: 1.1.0-alpha01')上,您可以从技术上为EncryptedSharedPreection创建实现,除了上面的getOrcreate()函数状态仅适用于API 23及以上版本。因此,如果我理解正确,我唯一缺少的就是能够执行以下代码行:

private fun createSharedPref(context: Context): SharedPreferences {
    return create(
        "secret_shared_prefs",
        masterKeyAlias,
        context,
        PrefKeyEncryptionScheme.AES256_SIV,
        PrefValueEncryptionScheme.AES256_GCM
    )
}

是创建我自己的自定义万事达密钥。在API 21中有没有办法做到这一点?

到目前为止,我是这样编码的:

class SharedPreferencesUtil {
    companion object {
        private val masterKeyAlias = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
        } else {
            TODO("VERSION.SDK_INT < M")
            //I need help here
        }


        private fun createSharedPref(context: Context): SharedPreferences {
            return create(
                "secret_shared_prefs",
                masterKeyAlias,
                context,
                PrefKeyEncryptionScheme.AES256_SIV,
                PrefValueEncryptionScheme.AES256_GCM
            )
        }


        fun saveObject(context: Context, key: String, data: Any) {
            val gson = Gson()
            val json = gson.toJson(data)
            val prefs = createSharedPref(context)
            prefs.edit().putString(key, json).apply()
        }


        fun getJson(context: Context, key: String): String {
            val prefs = createSharedPref(context)
            val json = prefs.getString(key, "null")
            return json!!
        }


        fun clearPreferences(context: Context) {
            val prefs = createSharedPref(context).edit()
            //remove my data
        }
    }
}

共有1个答案

郗阳德
2023-03-14

我找到了一个有效的解决方案(来源)

我将主密钥的实现替换为以下内容:

private fun createMasterKey(context: Context): String {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
    } else {
        val alias = "your_alias"
        val start: Calendar = GregorianCalendar()
        val end: Calendar = GregorianCalendar()
        end.add(Calendar.YEAR, 30)

        val spec =
            KeyPairGeneratorSpec.Builder(context) 
                .setAlias(alias)
                .setSubject(X500Principal("CN=$alias"))
                .setSerialNumber(
                    BigInteger.valueOf(
                        Math.abs(alias.hashCode()).toLong()
                    )
                )
                .setStartDate(start.time).setEndDate(end.time)
                .build()

        val kpGenerator: KeyPairGenerator = KeyPairGenerator.getInstance(
            "RSA",
            "AndroidKeyStore"
        )
        kpGenerator.initialize(spec)
        val kp: KeyPair = kpGenerator.generateKeyPair()
        kp.public.toString()
    }
}
 类似资料:
  • 问题内容: 注释如何与Java一起使用?以及如何创建这样的自定义注释: 基本上,我需要保留的POJO在持久化时像这样进行序列化: 这样,实际的生成/持久对象是这样的: 任何想法如何实现这一点? 问题答案: 如果创建自定义注释,则必须使用此处的 API 示例进行处理。您可以参考如何声明注释。 这是Java中的示例注释声明的样子。 并被称为。 表示您想在运行时保留注释,并且可以在运行时访问它。 表示您

  • 问题内容: 我在Django中启用了用户身份验证模块,但是当我使用它时,它仅询问用户名和两个密码/密码确认字段。我还希望将电子邮件和全名字段全部设置为必填字段。 我已经做到了: 现在,该表单显示了新字段,但是没有将它们保存到数据库中。 我怎样才能解决这个问题? 问题答案: 用户模型中没有调用此字段。 如果要使用原始模型存储名称,则必须将其分别存储为名字和姓氏。 编辑: 如果您只希望表单中的一个字段

  • 我正在使用helm charts创建部署微服务,通过执行helm create创建包含部署、服务和入口的基本图表,但我没有其他配置,如水平pod自动缩放器、pod中断预算。

  • 我们不仅可以分配事件处理程序,还可以从 JavaScript 生成事件。 自定义事件可用于创建“图形组件”。例如,我们自己的基于 JavaScript 的菜单的根元素可能会触发 open(打开菜单),select(有一项被选中)等事件来告诉菜单发生了什么。另一个代码可能会监听事件,并观察菜单发生了什么。 我们不仅可以生成出于自身目的而创建的全新事件,还可以生成例如 click 和 mousedow

  • 默认情况下,Navicat Monitor 从受监控的实例收集一组预设的服务器指标。你可能想要添加自己的查询,以收集特定实例的一些自定义性能指标,并在指标值超过某些阈值和持续时间时接收有关自定义数据的警报。若要配置自定义指标,请前往“配置”->“自定义指标”。 创建自定义指标和警报 在自定义指标页面中,点击“+ 新建自定义指标”。 【步骤一】输入自定义指标的定义: 指标名 输入自定义指标的名。 描

  • 使用Laravel 5.4.13,我有一个名为Widget的模型,我在其中设置主键如下: widgets表有一个主键列int,auto increment,名为:widget\u id。 但是,当我尝试在浏览器上更新记录时,我会出现以下错误: Connection.php第647行中的QueryException: SQLSTATE[42S22]:未找到列:1054“where子句”中的未知列“i