【发布时间】:2020-09-21 00:09:02
【问题描述】:
我正在使用 EncryptedSharedPreferences 来存储加密数据。
val biometricManager = BiometricManager.from(this)
val hasFingerprint = biometricManager.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS
val advanceSpec = KeyGenParameterSpec.Builder(
"master_key",
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).apply {
setBlockModes(KeyProperties.BLOCK_MODE_GCM)
setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
setKeySize(256)
if(hasFingerprint){
setUserAuthenticationRequired(true)
setUserAuthenticationValidityDurationSeconds(1)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
setInvalidatedByBiometricEnrollment(false)
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
setIsStrongBoxBacked(true)
setUserConfirmationRequired(true)
}
}
}.build()
val masterKey = MasterKeys.getOrCreate(advanceSpec)
val preferences = EncryptedSharedPreferences.create(
"TestPreferences",
masterKey,
applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
实际上,我错过了 BiometricPrompt 部分。我认为调用setUserAuthenticationRequired(true) 会自动处理身份验证用户。但我们必须自己显示 BiometricPrompt。 isUserAuthenticationRequired 仅确保只有在用户获得授权时才会激活密钥。
val biometricPrompt = BiometricPrompt(
activity,
ContextCompat.getMainExecutor(activity),
object: BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
createSharedPreferences()
}
}
)
biometricPrompt.authenticate(promptInfo)
但是,有一个问题。它只会在创建 EncryptedSharedPreferences 时抛出 UserNotAuthenticatedException。之后,我们可以根据需要执行读写操作。它没有考虑到setUserAuthenticationValidityDurationSeconds(1)。
【问题讨论】:
-
您能否在创建的加密共享首选项中存储和获取数据?
-
是的,我可以存储和获取数据。
-
你检查
hasFingerprint是否返回true? -
是的,它正在返回 true
-
对我来说,如果我没有明确要求用户使用
BiometricPromptdeveloper.android.com/training/sign-in/biometric-auth 进行身份验证,则在尝试创建 encryptedsharedpreference 对象时,您编写的代码会抛出UserNotAuthenticatedException。我正在使用运行 android 10 的 Smasung Galaxy M20。但我有点困惑,它允许我在创建其对象后编辑共享首选项,即使我执行超过 1 秒的身份验证时间的读写操作。
标签: android android-jetpack android-biometric encrypted-shared-preference android-jetpack-security