原文: Android指紋識别 上一篇 講了通過 FingerprintManager 驗證手機是否支援指紋識别,以及是否錄入了指紋,這裡進行指紋的驗證.
//擷取FingerprintManager執行個體
FingerprintManager mFingerprintManager =
(FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
//執行驗證監聽
mFingerprintManager
.authenticate(cryptoObject, mCancellationSignal, 0, this, null);
參數說明:
cryptoObject//FingerprintManager支援的加密對象的包裝類。目前該架構支援Signature,Cipher和Mac對象。
mCancellationSignal//提供取消正在進行的操作的功能。
callback(參數中的this)//指紋識别的回調函數
cryptoObject初始化:
private KeyguardManager mKeyguardManager;
private FingerprintManager mFingerprintManager;
private static final String DIALOG_FRAGMENT_TAG = "myFragment";
private static final String SECRET_MESSAGE = "Very secret message";
public static boolean isAuthenticating = false;
public static final String PARAM_DISMISS_DIALOG = "param_dismiss_dialog";
/**
* Alias for our key in the Android Key Store
*/
private static final String KEY_NAME = "my_key";
private KeyStore mKeyStore;
private KeyGenerator mKeyGenerator;
private Cipher mCipher;
@TargetApi(Build.VERSION_CODES.M)
private boolean initCipher() {
try {
mCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new RuntimeException("Failed to get an instance of Cipher", e);
}
try {
mKeyStore.load(null);
SecretKey key = (SecretKey) mKeyStore.getKey(KEY_NAME, null);
mCipher.init(Cipher.ENCRYPT_MODE, key);
return true;
} catch (KeyPermanentlyInvalidatedException e) {
return false;
} catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
| NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Failed to init Cipher", e);
}
}
/**
* Creates a symmetric key in the Android Key Store which can only be used after the user has
* authenticated with fingerprint.
*/
@TargetApi(Build.VERSION_CODES.M)
public void createKey() {
// The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint
// for your flow. Use of keys is necessary if you need to know if the set of
// enrolled fingerprints has changed.
mKeyStore = null;
mKeyGenerator = null;
try {
mKeyStore = KeyStore.getInstance("AndroidKeyStore");
} catch (KeyStoreException e) {
throw new RuntimeException("Failed to get an instance of KeyStore", e);
}
try {
mKeyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
throw new RuntimeException("Failed to get an instance of KeyGenerator", e);
}
try {
mKeyStore.load(null);
// Set the alias of the entry in Android KeyStore where the key will appear
// and the constrains (purposes) in the constructor of the Builder
mKeyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
// Require the user to authenticate with a fingerprint to authorize every use
// of the key
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
mKeyGenerator.generateKey();
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
| CertificateException | IOException e) {
throw new RuntimeException(e);
}
}
FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(mCipher);
回調函數:
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
//驗證出現錯誤了
//errString為錯誤的資訊
}
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
showError(helpString);
//驗證出現一些問題的系統提示,比如:請按久一點等提示資訊.
}
@Override
public void onAuthenticationFailed() {
showError("指紋驗證失敗");
//在驗證失敗和出現問題以後,系統會繼續執行監聽,使用者需要在這裡修改相關提示資訊
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
//驗證成功
}