問題描述
手機更換指紋時後,之前配合使用的密鑰Cipher失效,爆出
Key permanently invalidated (該密鑰已被永久無效)錯誤
然後返回給BiometricPrompt 使用時報錯:
Caused by: java.lang.IllegalStateException: Crypto primitive not initialized
解決辦法
對已經報錯的密鑰,進行刪除操作:
_keystore.deleteEntry(KEY_NAME);
而後重新獲取新的密鑰
/**
* 獲取key
*/
Key GetKey() throws Exception {
Key secretKey;
if (!_keystore.isKeyEntry(KEY_NAME)) {
return CreateKey();
}
secretKey = _keystore.getKey(KEY_NAME, null);
return secretKey;
}
/**
* 創建key
*/
@RequiresApi(api = Build.VERSION_CODES.M)
Key CreateKey() throws Exception {
Log.e(TAG, "CreateKey ");
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);
SecretKey secretKey = keyGen.generateKey();
return secretKey;
}
並進行初始化(關鍵)
Cipher createCipher(boolean retry, int operMode, byte[] iv) throws Exception {
Key key = GetKey();
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
try {
if (operMode == Cipher.ENCRYPT_MODE) {
cipher.init(Cipher.ENCRYPT_MODE, key);
} else if (operMode == Cipher.DECRYPT_MODE) {
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
}
} catch (KeyPermanentlyInvalidatedException e) {
// 該密鑰已被永久無效 Key permanently invalidated
Log.e(TAG, "createCipher: "+e.getMessage() );
_keystore.deleteEntry(KEY_NAME);
if (retry) {
return createCipher(false, operMode, iv);
} else {
throw new Exception("Could not create the cipher for fingerprint authentication.", e);
}
}
return cipher;
}
並且非常要注意的一點是, 當返回的時候, 重複執行的createCipher方法 遞歸, 遞歸返回時的結果值,第一次運行返回的是第一次執行的, 如果在retry 之後沒有進行return createCipher 那麼即使執行了第二次,返回的依舊是第一次的值!
有問題可隨時聯繫QQ, 7641436
需要Android 最新X庫 指紋識別(同時兼容api23&api28)並配合AndroidKetStore密鑰存儲的可以私聊我。