# FingerprintVerification **Repository Path**: hm0603/FingerprintVerification ## Basic Information - **Project Name**: FingerprintVerification - **Description**: 指纹验证 - **Primary Language**: Android - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2018-09-14 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 指纹识别 ## Android 6.0到8.1的使用方式 需要的权限 ``` ``` ## 核心代码 获取指纹管理对象 ``` FingerprintManagerCompat fingerprintManagerCompat = FingerprintManagerCompat.from(this); ``` 判断指纹是否可用 ``` /** * 是否可以使用 指纹识别 * * @param managerCompat 指纹识别模块管理对象(向下兼容) * @return 是否可用 */ private boolean canUseFingerprint(FingerprintManagerCompat managerCompat) { // 手机是否有职位识别模块 if (!managerCompat.isHardwareDetected()) return false; //是否已经录入指纹 return managerCompat.hasEnrolledFingerprints(); } ``` 开始指纹识别 ``` //指纹验证取消信号对象 (用于控制取消指纹验证) CancellationSignal cancellationSignal = new CancellationSignal(); /** * @param crypto 与调用关联的对象,如果不需要则为null. * @param flags 系统预留属性,此时应该为 0 * @param cancel 控制取消指纹信号的对象 * @param callback 指纹验证结果的回调函数 * @param handler 指纹验证结果的 Handle 对象,一般使用 callback即可,向了解关于 handler 的使用跟踪以下源码就一目了然 {@link FingerprintManager)} */ fingerprintManagerCompat.authenticate(null, 0, cancellationSignal, new FingerprintCallback(), null); //fingerprintManagerCompat.authenticate(new CryptoObjectHelper().buildCryptoObject(), 0, cancellationSignal, new FingerprintCallback(), null); ``` 取消指纹验证 ``` //指纹验证是否取消 if (!cancellationSignal.isCanceled()) { //取消指纹验证 cancellationSignal.cancel(); } ``` 指纹验证结果的回调 ``` private class FingerprintCallback extends FingerprintManagerCompat.AuthenticationCallback { /** * 当多次验证失败,该方法被调用,并且在将来的一段时间内不能在使用指纹验证.或 用户手动取消验证等... * * @param errMsgId 错误状态ID 可能是 {@link FingerprintManager#FINGERPRINT_ERROR_HW_UNAVAILABLE} * ,or {@link FingerprintManager#FINGERPRINT_ERROR_UNABLE_TO_PROCESS} * ,or {@link FingerprintManager#FINGERPRINT_ERROR_TIMEOUT} 验证超时 * ,or {@link FingerprintManager#FINGERPRINT_ERROR_NO_SPACE} * ,or {@link FingerprintManager#FINGERPRINT_ERROR_CANCELED} 取消验证 {@link CancellationSignal#cancel()} 被调用 * ,or {@link FingerprintManager#FINGERPRINT_ERROR_LOCKOUT} 多次验证失败 * ,or {@link FingerprintManager#FINGERPRINT_ERROR_VENDOR} * ,or {@link FingerprintManager#FINGERPRINT_ERROR_LOCKOUT_PERMANENT} * ,or {@link FingerprintManager#FINGERPRINT_ERROR_USER_CANCELED} 其中一个. * @param errString 错误提示信息 */ @Override public void onAuthenticationError(int errMsgId, CharSequence errString) { super.onAuthenticationError(errMsgId, errString); } /** * 在验证过程中,遇到可恢复的异常时该方法被调用.(传感器脏,请把它擦干净。...) * * @param helpMsgId * @param helpString 提示信息 */ @Override public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { super.onAuthenticationHelp(helpMsgId, helpString); } /** * 指纹验证成功 * * @param result */ @Override public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) { super.onAuthenticationSucceeded(result); } /** * 指纹验证失败 */ @Override public void onAuthenticationFailed() { super.onAuthenticationFailed(); } } ``` ### 通用指纹验证加密对象 ``` public class CryptoObjectHelper { //TODO 这可以是您想要的关键名称。该应用程序应该是唯一的。(一般使用 应用包名) private static final String KEY_NAME = "com.example.linhuaming.fingerprint_authentication_key"; // We always use this keystore on Android. private static final String KEYSTORE_NAME = "AndroidKeyStore"; // Should be no need to change these values. private static final String KEY_ALGORITHM = KeyProperties.KEY_ALGORITHM_AES; private static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC; private static final String ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7; private static final String TRANSFORMATION = KEY_ALGORITHM + "/" + BLOCK_MODE + "/" + ENCRYPTION_PADDING; private KeyStore _keystore; public CryptoObjectHelper() { try { _keystore = KeyStore.getInstance(KEYSTORE_NAME); _keystore.load(null); } catch (KeyStoreException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } } public FingerprintManagerCompat.CryptoObject buildCryptoObject() { try { Cipher cipher = createCipher(true); if (cipher != null) { return new FingerprintManagerCompat.CryptoObject(cipher); } } catch (Exception e) { e.printStackTrace(); } return null; } private Cipher createCipher(boolean retry) throws Exception { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return null; Key key = GetKey(); Cipher cipher = Cipher.getInstance(TRANSFORMATION); try { cipher.init(Cipher.ENCRYPT_MODE | Cipher.DECRYPT_MODE, key); } catch (KeyPermanentlyInvalidatedException e) { _keystore.deleteEntry(KEY_NAME); if (retry) { createCipher(false); } else { throw new Exception("Could not create the cipher for fingerprint authentication.", e); } } return cipher; } @RequiresApi(api = Build.VERSION_CODES.M) private Key GetKey() throws Exception { Key secretKey; if (!_keystore.isKeyEntry(KEY_NAME)) { CreateKey(); } secretKey = _keystore.getKey(KEY_NAME, null); return secretKey; } @RequiresApi(api = Build.VERSION_CODES.M) private void CreateKey() throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance(KEY_ALGORITHM, KEYSTORE_NAME); KeyGenParameterSpec keyGenSpec = new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(BLOCK_MODE) .setEncryptionPaddings(ENCRYPTION_PADDING) .setUserAuthenticationRequired(true) .build(); keyGen.init(keyGenSpec); keyGen.generateKey(); } } ``` ## Android 9.0 生物识别 > 在Android 9.0 中 指纹识别 Api 已经被废弃 后续完善...敬请期待...