首页 > 程序开发 > 移动开发 > Android >

Android之指纹解锁

2017-03-29

Android之指纹解锁,最近项目里需要用到指纹解锁的功能,所以也是各种查资料,在这里总结一下。指纹解锁是Android6 0新增的功能,因此在使用的时候需要先判断用户的手机版本是否支持指纹解锁。

Android之指纹解锁,最近项目里需要用到指纹解锁的功能,所以也是各种查资料,在这里总结一下。

指纹解锁是Android6.0新增的功能,因此在使用的时候需要先判断用户的手机版本是否支持指纹解锁。

使用指纹识别的对称加密功能的主要流程如下:
1、使用 KeyGenerator 创建一个对称密钥,存放在 KeyStore 里。
2、设置KeyGenParameterSpec.Builder.setUserAuthenticationRequired() 为true。
3、使用创建好的对称密钥初始化一个Cipher对象,并用该对象调用 FingerprintManager.authenticate() 方法启动指纹传感器并开始监听。
4、重写 FingerprintManager.AuthenticationCallback 的几个回调方法,以处理指纹识别成功(onAuthenticationSucceeded())、失败(onAuthenticationFailed() 和 onAuthenticationError())等情况。

创建密钥:

创建密钥要涉及到两个类:KeyStore 和 KeyGenerator。

KeyStore 是用于存储、获取密钥(Key)的容器,获取 KeyStore的方法如下:
try {
keyStore = KeyStore.getInstance(“AndroidKeyStore”);
keyStore.load(null);
} catch (Exception e) {
e.printStackTrace();
}

而生成 Key,如果是对称加密,就需要 KeyGenerator 类。获取一个 KeyGenerator 对象比较简单,方法如下:

// 对称加密, 创建 KeyGenerator 对象
try {
mKeyGenerator = KeyGenerator
.getInstance(KeyProperties.KEY_ALGORITHM_AES, “AndroidKeyStore”);
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
throw new RuntimeException(“Failed to get an instance of KeyGenerator”, e);
}

获得 KeyGenerator 对象后,就可以生成一个 Key 了:
KeyGenerator mKeyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM, KEYSTORE_NAME);
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder
(KEY_NAME, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
mKeyGenerator.init(builder.build());
mKeyGenerator.generateKey();

创建并初始化 Cipher 对象

Cipher 对象是一个按照一定的加密规则,将数据进行加密后的一个对象。调用指纹识别功能需要使用到这个对象。创建 Cipher 对象很简单,如同下面代码那样:

cipher = Cipher.getInstance(TRANSFORMATION);

cipher.init(Cipher.ENCRYPT_MODE | Cipher.DECRYPT_MODE, key);

使用指纹识别功能

调用 FingerprintManager 类的的方法authenticate()而已,然后系统会有相应的回调反馈给我们,该方法如下:

public void authenticate(CryptoObject crypto, CancellationSignal cancel, int flags, AuthenticationCallback callback, Handler handler)

该方法的几个参数解释如下:
1、是一个加密对象。还记得之前我们大费周章地创建和初始化的Cipher对象吗?这里的 CryptoObject 对象就是使用 Cipher 对象创建创建出来的:new FingerprintManager.CryptoObject(cipher)。
2、是一个 CancellationSignal 对象,该对象提供了取消操作的能力。创建该对象也很简单,使用 new CancellationSignal() 就可以了。
3、是一个标志,默认为0。
4、是 AuthenticationCallback 对象,它本身是 FingerprintManager 类里面的一个抽象类。该类提供了指纹识别的几个回调方法,包括指纹识别成功、失败等。需要我们重写。
5、Handler,可以用于处理回调事件,可以传null。

完成指纹识别后,还要记得将 AuthenticationCallback 关闭掉:

if (mCancellationSignal != null) {
mCancellationSignal.cancel();
mCancellationSignal = null;
}

重写回调方法
调用了 authenticate() 方法后,系统就会启动指纹传感器,并开始扫描。这时候根据扫描结果,会通过FingerprintManager.AuthenticationCallback类返回几个回调方法:

// 成功
onAuthenticationSucceeded()
// 失败
onAuthenticationFaile()
// 错误
onAuthenticationError()

实际应用中的注意事项

判断用户是否可以使用指纹识别功能

一般来说,为了增加安全性,要求用户在手机的“设置”中开启了密码锁屏功能。当然,使用指纹解锁的前提是至少录入了一个指纹。

// 如果没有设置密码锁屏,则不能使用指纹识别
if (!keyguardManager.isKeyguardSecure()) {
Toast.makeText(this, “请在设置界面开启密码锁屏功能”,
Toast.LENGTH_LONG).show();
}
// 如果没有录入指纹,则不能使用指纹识别
if (!fingerprintManager.hasEnrolledFingerprints()) {
Toast.makeText(this, “您还没有录入指纹, 请在设置界面录入至少一个指纹”,
Toast.LENGTH_LONG).show();
}

关于这三个回调方法,有几点需要注意的:
1.当指纹识别失败后,会调用onAuthenticationFailed()方法,这时候指纹传感器并没有关闭,系统给我们提供了5次重试机会,也就是说,连续调用了5次onAuthenticationFailed()方法后,会调用onAuthenticationError()方法。
2.当系统调用了onAuthenticationError()和onAuthenticationSucceeded()后,传感器会关闭,只有我们重新授权,再次调用authenticate()方法后才能继续使用指纹识别功能。
3.当系统回调了onAuthenticationError()方法关闭传感器后,这种情况下再次调用authenticate()会有一段时间的禁用期,也就是说这段时间里是无法再次使用指纹识别的。当然,具体的禁用时间由手机厂商的系统不同而有略微差别,有的是1分钟,有的是30秒等等。而且,由于手机厂商的系统区别,有些系统上调用了onAuthenticationError()后,在禁用时间内,其他APP里面的指纹识别功能也无法使用,甚至系统的指纹解锁功能也无法使用。而有的系统上,在禁用时间内调用其他APP的指纹解锁功能,或者系统的指纹解锁功能,就能立即重置指纹识别功能。

示例代码
最后, 关于指纹的示例代码地址如下:https://github.com/zhaopingfu/TestFingerprint

相关文章
最新文章
热点推荐