添加了安卓指纹检测新手指



如何检测用户在我的应用程序中验证手指后是否向Android设置添加了新指纹?

即iOS有一个名为(evaluatedPolicyDomainState)的东西来检测指纹目录中的变化,Android中的替代方案是什么?

在这种情况下,出于安全原因,这需要提示密码

来自setUserAuthenticationRequired的文档:

一旦禁用安全锁定屏幕(

重新配置为无、滑动或其他不对用户进行身份验证的模式)或强制重置安全锁定屏幕(例如,由设备管理员重置),密钥将不可逆转地失效。此外,如果密钥要求每次使用密钥时都进行用户身份验证,则一旦注册了新指纹或不再注册指纹,该密钥也将不可逆转地失效,除非setInvalidatedByBiometricEnrollment(boolean)用于在注册后允许有效性。尝试使用此类密钥初始化加密操作将引发 KeyPermanentlyInvalidatedException。

因此,要检查自创建指纹关联密钥以来是否已注册任何新指纹,只需使用该密钥创建密码并尝试init密码即可。如果已注册任何新指纹,则init调用应触发KeyPermanentlyInvalidatedException

我可以以整数形式获取所有手指 id。

private void getFingerprintInfo(Context context) 
{
try {
FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Method method = FingerprintManager.class.getDeclaredMethod("getEnrolledFingerprints");
Object obj = method.invoke(fingerprintManager);
if (obj != null) {
Class<?> clazz = Class.forName("android.hardware.fingerprint.Fingerprint");
Method getFingerId = clazz.getDeclaredMethod("getFingerId");
for (int i = 0; i < ((List) obj).size(); i++)
{
Object item = ((List) obj).get(i);
if(item != null)
{
System.out.println("fkie4. fingerId: " + getFingerId.invoke(item));
}
}
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
e.printStackTrace();
}
}

请参考: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/hardware/fingerprint/Fingerprint.java

有一个公共方法 getFingerId( ),但它不能被我们调用,因为它有"@UnsupportedAppUsage"。

因此,您需要使用反射来调用该方法。 获取指纹 ID 列表后,您可以加密它们并存储在共享首选项中。

手指 ID 是存储在设置中的指纹的 ID

获取所有指纹 ID 后,您可以确定用户是否已添加/删除指纹。

无需依赖密钥永久无效异常。它不会在安卓 8.0 中抛出

祝你好运!!!...

不相信谷歌做得这么差

private String getFingerprintInfo(Context context) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Method method = FingerprintManager.class.getDeclaredMethod("getEnrolledFingerprints");
Object obj = method.invoke(fingerprintManager);
String allFingerPrintInfo = "";
if (obj != null) {
Class<?> clazz = Class.forName("android.hardware.fingerprint.Fingerprint");
for (int i = 0; i < ((List) obj).size(); i++) {
Object fingerPrint = ((List) obj).get(i);
if (fingerPrint != null) {
String fingerPrintInfo = "";
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
Parcel p = Parcel.obtain();
p.setDataPosition(0);
//                        Method writeToParcel = clazz.getDeclaredMethod("writeToParcel", Parcel.class, Integer.class);
clazz.getDeclaredMethods()[1].invoke(fingerPrint, p, 0);
p.setDataPosition(0);
fingerPrintInfo = p.readString() + "_" + p.readInt() + "_" + p.readLong();
} else {
Method getFingerId = clazz.getDeclaredMethod("getFingerId");
fingerPrintInfo = (String) getFingerId.invoke(fingerPrint);
}
allFingerPrintInfo += fingerPrintInfo + "*";
}
}
}
return allFingerPrintInfo;
}
/**
* Generate NIST P-256 EC Key pair for signing and verification
*
* @param keyName
* @param invalidatedByBiometricEnrollment
* @return
* @throws Exception
*/
@TargetApi(Build.VERSION_CODES.P)
private KeyPair generateKeyPair(String keyName, boolean invalidatedByBiometricEnrollment) throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,
KeyProperties.PURPOSE_SIGN)
.setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
.setDigests(KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA384,
KeyProperties.DIGEST_SHA512)
// Require the user to authenticate with a biometric to authorize every use of the key
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(invalidatedByBiometricEnrollment);
keyPairGenerator.initialize(builder.build());
return keyPairGenerator.generateKeyPair();
}

您无法从应用添加新指纹。

在您的应用程序中,您只能访问身份验证指纹方法,该方法通过密钥存储检查注册的指纹。

最新更新