添加新生物识别时使 SecretKey 无效
Invalidate SecretKey when new Biometrics are added
我 运行 遇到一个问题,当用户将新指纹添加到他们的 Android 设备时,我想使 SecretKey 失效。我可以生成密钥,毫无问题地提取生物识别提示。当我添加一个新的指纹时,密钥没有抛出异常..它仍然允许出现提示。
我可以从设备中删除所有指纹,并抛出 KeyPermanentlyInvalidatedException。
我正在使用 BiometricPrompt AndroidX 库,我的 minSDK 设置为 28。我一直在遵循这个指南:https://developer.android.com/training/sign-in/biometric-auth#crypto
我的代码如下 - 如果有人愿意帮助我解决这个问题,我将不胜感激。
package com.example.dogtime
import android.os.Bundle
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyPermanentlyInvalidatedException
import android.security.keystore.KeyProperties
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
import butterknife.ButterKnife
import java.security.KeyStore
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
class MainActivity : AppCompatActivity() {
private lateinit var biometricPrompt: BiometricPrompt
private lateinit var biometricPromptInfo: BiometricPrompt.PromptInfo
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ButterKnife.bind(this)
setContentView(R.layout.activity_main)
// Set up prompt
biometricPrompt = BiometricPrompt(
this,
ContextCompat.getMainExecutor(baseContext),
object : BiometricPrompt.AuthenticationCallback() {
// no-op
}
)
// Prompt info
biometricPromptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Title")
.setNegativeButtonText("Test")
.build()
// Generates key
findViewById<Button>(R.id.count_btn).setOnClickListener {
generateKey()
}
// Shows biometric prompt
findViewById<Button>(R.id.random_btn).setOnClickListener {
getCrypto()?.let { it1 -> biometricPrompt.authenticate(biometricPromptInfo, it1) }
?: run {
// Key is invalidated - this is never triggered
}
}
}
private fun generateKey() {
val keyGenerator = KeyGenerator
.getInstance(KeyProperties
.KEY_ALGORITHM_AES, "AndroidKeyStore")
keyGenerator.init(getKeyGen())
keyGenerator.generateKey()
}
private fun getCipher() : Cipher {
return Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7
)
}
private fun getKey() : SecretKey {
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
return keyStore.getKey("key6", null) as SecretKey
}
private fun getKeyGen() : KeyGenParameterSpec {
return KeyGenParameterSpec.Builder(
"key6",
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build()
}
private fun getCrypto() : BiometricPrompt.CryptoObject? {
return try {
val cipher = getCipher()
val key = getKey()
cipher.init(Cipher.ENCRYPT_MODE, key)
BiometricPrompt.CryptoObject(cipher)
} catch(e: KeyPermanentlyInvalidatedException) {
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
keyStore.deleteEntry("key6")
null
}
}
}
(回答我自己的问题)。我已将其与上述解决方案一起用于以下设备规格。
- 设备:三星 A31、Pixel 2XL
- Android版本:10
- 生物识别:指纹
之前我是用模拟器测试的,密钥不会失效。我不确定为什么,但模拟器测试无法有效地测试这种情况。
我 运行 遇到一个问题,当用户将新指纹添加到他们的 Android 设备时,我想使 SecretKey 失效。我可以生成密钥,毫无问题地提取生物识别提示。当我添加一个新的指纹时,密钥没有抛出异常..它仍然允许出现提示。
我可以从设备中删除所有指纹,并抛出 KeyPermanentlyInvalidatedException。
我正在使用 BiometricPrompt AndroidX 库,我的 minSDK 设置为 28。我一直在遵循这个指南:https://developer.android.com/training/sign-in/biometric-auth#crypto
我的代码如下 - 如果有人愿意帮助我解决这个问题,我将不胜感激。
package com.example.dogtime
import android.os.Bundle
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyPermanentlyInvalidatedException
import android.security.keystore.KeyProperties
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
import butterknife.ButterKnife
import java.security.KeyStore
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
class MainActivity : AppCompatActivity() {
private lateinit var biometricPrompt: BiometricPrompt
private lateinit var biometricPromptInfo: BiometricPrompt.PromptInfo
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ButterKnife.bind(this)
setContentView(R.layout.activity_main)
// Set up prompt
biometricPrompt = BiometricPrompt(
this,
ContextCompat.getMainExecutor(baseContext),
object : BiometricPrompt.AuthenticationCallback() {
// no-op
}
)
// Prompt info
biometricPromptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Title")
.setNegativeButtonText("Test")
.build()
// Generates key
findViewById<Button>(R.id.count_btn).setOnClickListener {
generateKey()
}
// Shows biometric prompt
findViewById<Button>(R.id.random_btn).setOnClickListener {
getCrypto()?.let { it1 -> biometricPrompt.authenticate(biometricPromptInfo, it1) }
?: run {
// Key is invalidated - this is never triggered
}
}
}
private fun generateKey() {
val keyGenerator = KeyGenerator
.getInstance(KeyProperties
.KEY_ALGORITHM_AES, "AndroidKeyStore")
keyGenerator.init(getKeyGen())
keyGenerator.generateKey()
}
private fun getCipher() : Cipher {
return Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7
)
}
private fun getKey() : SecretKey {
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
return keyStore.getKey("key6", null) as SecretKey
}
private fun getKeyGen() : KeyGenParameterSpec {
return KeyGenParameterSpec.Builder(
"key6",
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build()
}
private fun getCrypto() : BiometricPrompt.CryptoObject? {
return try {
val cipher = getCipher()
val key = getKey()
cipher.init(Cipher.ENCRYPT_MODE, key)
BiometricPrompt.CryptoObject(cipher)
} catch(e: KeyPermanentlyInvalidatedException) {
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
keyStore.deleteEntry("key6")
null
}
}
}
(回答我自己的问题)。我已将其与上述解决方案一起用于以下设备规格。
- 设备:三星 A31、Pixel 2XL
- Android版本:10
- 生物识别:指纹
之前我是用模拟器测试的,密钥不会失效。我不确定为什么,但模拟器测试无法有效地测试这种情况。