问题研究

Android 指纹解锁

2020-02-25  本文已影响0人  Android_冯星

指纹数据是在手机的设置里面,不是存到自己写的APP的。其次,指纹识别就只能识别,而不能在APP中录入指纹,想录入指纹可以,自己要到手机设置里面的指纹功能自己去添加,指纹识别功能能做的就是把用户放到感应区的指纹数据与手机设置里面的已录入的指纹数据进行比对,再执行成功失败的回调,仅此而已

指纹识别是在Android 6.0之后新增的功能,因此在使用的时候需要先判断用户手机的系统版本是否支持指纹识别。另外,实际开发场景中,使用指纹的主要场景有两种:

由于使用指纹识别功能需要一个加密对象(CryptoObject)该对象一般是由对称加密或者非对称加密获得。

上述两种开发场景的实现大同小异,主要区别在于加密过程中密钥的创建和使用,一般来说:

指纹识别 API 的版本演进

在 Android 6.0(Android M Api23),Android 系统开放了指纹识别的api,存在于 android.hardware.fingerprint包下,核心类是FingerprintManager,提供了基础的指纹识别的功能。要注意的是,FingerprintManager在 Android 9.0(Android P Api28)做了 @Deprecated 标记,将被弃用。

后来,在android.support.v4.hardware.fingerprint包和 androidx.core.hardware.fingerprint包中,FingerprintManager升级为了 FingerprintManagerCompat,对功能进行了增强,也做了一些兼容性的处理,比如增加了系统版本号的判断,对指纹支持加密处理等。实际上阅读源码会发现,他的核心功能还是调用 FingerprintManager 实现的。

再之后,在 Android 9.0(Android P Api 28),Google 对生物识别进行了进一步增强,开放了以 BiometricPrompt 为核心的新 Api,存在于 androidx.biometric 包和android.hardware.biometrics包下,Google 在开发者文档中是这样解释的:

On devices running P and above, this will show a system-provided authentication prompt, using a device's supported biometric (fingerprint, iris, face, etc).

大意是,在 Android P 及以上版本的系统中,BiometricPrompt 将展现一个由系统提供的验证提示,用于支持设备提供的生物识别,包括指纹、虹膜、面部等。

目前来看,虹膜和面部等生物识别 Api 尚未开放,仅支持指纹识别,不过在指纹识别上进行了统一,比如要求使用统一的指纹识别 UI ,不允许开发者自定义了。

android9.0问题
(1) Android 9.0 不允许开发者自定义指纹识别框,但系统提供的指纹识别框的灵活性堪忧。比如说,目前来看,系统只允许在识别框出现一个按钮,放了 “取消” 就不能放 “密码验证” ,放了 “密码验证” 就不能放 “取消”。

(2) 系统提供的指纹识别框只能在界面底部,不可以上下居中。但在某些手机上(如OPPO reno),指纹传感器也是在界面底部,当拉起指纹识别时,会在指纹传感器的位置显示一个指纹图标,以提示用户在哪下指。然而,系统提供的指纹识别框上也有一个指纹图标,这两个指纹图标就发生了重合或者离的很近。
解释:

(1)TAM中心是用于存储密钥的服务;

(2)TEE是手机中的独立环境,目前没有有效的破解方法;

(3)APP就是客户端;

(4)后台应用便是后台服务器;

(5)整个验证流程属于三层加密,分别是ATTK,ASK,AUTHKEY;它们分别都有私钥pri和公钥pub,加密时通常用上层私钥加密下层公钥生成密串,然后用下层私钥进行解密。

指纹登录

Google原生API:https://developer.android.com/reference/android/hardware/fingerprint/package-summary.html

阿里指纹2.0:http://open.yunos.com/doc/detail?documentId=102937#

微信soter:https://github.com/Tencent/soter

Google原生API

使用简单不安全。

1.指纹主要返回的就是true和false:

只要你的手机录入过指纹,那么就可以验证指纹通过。那么,假如手机的锁屏密码被知道了,被熊孩子不小心看到,然后他偷偷录入了自己的指纹。最后,他就可以通过这个指纹进行各种验证。换句话说,非常安全的生物指纹,直接降低到了锁屏密码的安全级别;

2.密钥对被劫持:

goolge允许用户在应用中生成一对非对称密钥,将私钥存储在TEE中。但是,如果在密钥生成的时候就被拦截并替换成了黑客自己的密钥,那么也会出现问题;

指纹识别核心方法 authenticate

mCancellationSignal = new CancellationSignal();
        fingerprintManager.authenticate(new FingerprintManager.CryptoObject(cipher), mCancellationSignal, 0, new FingerprintManager.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode, CharSequence errString) {
                if (!isSelfCancelled) {
                    errorMsg.setText(errString);
                    if (errorCode == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT) {
                        Toast.makeText(mActivity, errString, Toast.LENGTH_SHORT).show();
                        dismiss();
                    }
                }
            }

            @Override
            public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
                errorMsg.setText(helpString);
            }

            @Override
            public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
                FingerprintManager.CryptoObject cryptoObject = result.getCryptoObject();
                Cipher cipher1 = cryptoObject.getCipher();
                try {
                    byte[] bytes = cipher1.doFinal();
                    byte[] bytes1 = cipher.doFinal();
                } catch (BadPaddingException e) {
                    e.printStackTrace();
                } catch (IllegalBlockSizeException e) {
                    e.printStackTrace();
                }
                Toast.makeText(mActivity, "指纹认证成功", Toast.LENGTH_SHORT).show();
                mActivity.onAuthenticated();
            }

            @Override
            public void onAuthenticationFailed() {
                errorMsg.setText("指纹认证失败,请再试一次");

            }
        }, null);

参数解析

接口回调

校验指纹功能是否可用

  private boolean supportFingerprint() {
        if (Build.VERSION.SDK_INT < 23) {
            Toast.makeText(this, "您的系统版本过低,不支持指纹功能", Toast.LENGTH_SHORT).show();
            return false;
        } else {
            KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
            FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
            if (!fingerprintManager.isHardwareDetected()) {
                Toast.makeText(this, "您的手机不支持指纹功能", Toast.LENGTH_SHORT).show();
                return false;
            }
//            else if (!keyguardManager.isKeyguardSecure()) {
//                Toast.makeText(this, "您还未设置锁屏,请先设置锁屏并添加一个指纹", Toast.LENGTH_SHORT).show();
//                return false;
//            }
            else if (!fingerprintManager.hasEnrolledFingerprints()) {
                Toast.makeText(this, "您至少需要在系统设置中添加一个指纹", Toast.LENGTH_SHORT).show();
                return false;
            }
        }
        return true;
    }
上一篇 下一篇

猜你喜欢

热点阅读