密钥库无法加载 ID 为:_androidx_security_master_key_的密钥

问题描述 投票:0回答:2

我正在尝试使用 masterKey 来加密共享首选项。但是,有时我的用户会由于密钥库中的 invalidKeyException 而崩溃。我无法在本地重现这个=\

 java.security.KeyStoreException: the master key android-keystore://_androidx_security_master_key_ exists but is unusable


 Caused by: java.security.InvalidKeyException: Keystore cannot load the key with ID: _androidx_security_master_key_

有什么想法为什么会发生这种情况吗?

    val masterKey = MasterKey.Builder(context)
        .setKeyGenParameterSpec(
            KeyGenParameterSpec.Builder(
                MasterKey.DEFAULT_MASTER_KEY_ALIAS,
                PURPOSE_ENCRYPT or PURPOSE_DECRYPT
            )
                .setBlockModes(BLOCK_MODE_GCM)
                .setEncryptionPaddings(ENCRYPTION_PADDING_NONE)
                .setKeySize(MasterKey.DEFAULT_AES_GCM_MASTER_KEY_SIZE)
                .build()
        )
        .build()
    securePrefs = EncryptedSharedPreferences.create(
        context,
        PREFERENCES,
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
android keystore
2个回答
9
投票

该问题也已详细报告给 Google 错误跟踪器。关注那里的讨论可能会更好。

https://issuetracker.google.com/issues/176215143


1
投票

您可以在此处查看 Android 问题:https://issuetracker.google.com/issues/176215143?pli=1

我可以建议简单的解决方法,从系统密钥库中删除首选项和密钥的数据。通过此修复,重新安装您的应用程序后无法恢复数据。但至少你的应用程序可以从新页面启动而不会崩溃。您可以创建一些自定义构建器并使用它来创建加密首选项:

class EncryptedPreferenceBuilder(val context: Context) {


companion object {
    private const val TAG = "EncryptedPreferenceBuilder"
    private const val KEYSTORE_PROVIDER = "AndroidKeyStore"
}

private val masterKeyAlias = MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build()

fun build(prefName: String): SharedPreferences {
    return try {
        createSharedPreferences(prefName)
    } catch (e: Exception) {
        Log.e(TAG, "Error occurred while create shared preference")
        deleteSharedPreferences(prefName)
        deleteMasterKey()
        createSharedPreferences(prefName)
    }
}

private fun createSharedPreferences(prefName: String) = EncryptedSharedPreferences.create(
    context,
    prefName,
    masterKeyAlias,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

private fun clearSharedPreference(prefName: String) {
    context.getSharedPreferences(prefName, Context.MODE_PRIVATE).edit().clear().apply()
}

private fun deleteSharedPreferences(prefName: String) {
    try {
        clearSharedPreference(prefName)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            context.deleteSharedPreferences(prefName)
        } else {
            FileUtils.delete("${context.filesDir.parent}/shared_prefs/$prefName.xml")
        }
    } catch (e: Exception) {
        Log.e(TAG, "Error delete preferences")
    }
}

private fun deleteMasterKey() {
    try {
        val keyStore = KeyStore.getInstance(KEYSTORE_PROVIDER)
        keyStore.load(null)
        keyStore.deleteEntry(MasterKey.DEFAULT_MASTER_KEY_ALIAS)
    } catch (e: Exception) {
        Log.e(TAG, "Error delete MasterKey")
    }
}
}

用途:

val prefs = EncryptedSharedPreferenceBuilder(context).build("APP_PREFS_NAME")
© www.soinside.com 2019 - 2024. All rights reserved.