Android EncryptedSharedReferences isUserAuthenticationRequired无法正常工作
我正在使用EncryptedSharedReferences存储加密数据Android EncryptedSharedReferences isUserAuthenticationRequired无法正常工作,android,android-jetpack,android-biometric,encrypted-shared-preference,android-jetpack-security,Android,Android Jetpack,Android Biometric,Encrypted Shared Preference,Android Jetpack Security,我正在使用EncryptedSharedReferences存储加密数据 val biometricManager = BiometricManager.from(this) val hasFingerprint = biometricManager.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS val advanceSpec = KeyGenParameterSpec.Builder( "master_key",
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
)
事实上,我错过了提示部分。我认为调用setUserAuthenticationRequired(true)
会自动处理身份验证用户。但我们必须展示我们自己isUserAuthenticationRequired
仅确保仅当用户获得授权时才会激活密钥
val biometricPrompt = BiometricPrompt(
activity,
ContextCompat.getMainExecutor(activity),
object: BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
createSharedPreferences()
}
}
)
biometricPrompt.authenticate(promptInfo)
但是,有一个问题。创建
EncryptedSharedReferences
时,它仅抛出UserNotAuthenticatedException。之后,我们可以根据需要执行读写操作。它没有考虑设置用户身份验证有效性持续时间秒(1)我找到了它在1秒后不需要身份验证的原因。这是因为,一旦初始化加密的共享首选项,它将加载用于加密和解密内存中数据的密钥,然后这些密钥用于访问文件中的数据。您可以在EncryptedSharedReference
类中读取代码。这是很明显的
KeysetHandle daeadKeysetHandle = new AndroidKeysetManager.Builder()
.withKeyTemplate(prefKeyEncryptionScheme.getKeyTemplate())
.withSharedPref(context, KEY_KEYSET_ALIAS, fileName)
.withMasterKeyUri(KEYSTORE_PATH_URI + masterKeyAlias)
.build().getKeysetHandle();
KeysetHandle aeadKeysetHandle = new AndroidKeysetManager.Builder()
.withKeyTemplate(prefValueEncryptionScheme.getKeyTemplate())
.withSharedPref(context, VALUE_KEYSET_ALIAS, fileName)
.withMasterKeyUri(KEYSTORE_PATH_URI + masterKeyAlias)
.build().getKeysetHandle();
DeterministicAead daead = daeadKeysetHandle.getPrimitive(DeterministicAead.class);
Aead aead = aeadKeysetHandle.getPrimitive(Aead.class);
return new EncryptedSharedPreferences(fileName, masterKeyAlias,
context.getSharedPreferences(fileName, Context.MODE_PRIVATE), aead, daead);
您是否能够在创建的加密共享首选项中存储和获取数据?是的,我能够存储和获取数据。您是否检查了
hasFingerprint
是否返回true?是的,它为我返回true,您编写的代码在尝试创建EncryptedSharedReference对象时抛出了UserNotAuthenticationDexception
,如果我没有明确要求用户使用生物特征提示进行身份验证的话。我使用的是运行安卓10的Smasung Galaxy M20。但我有点困惑,它允许我在创建了SharedReference对象之后编辑它,即使我在1秒的身份验证时间之后执行读写操作。