我在 Android KeyStore 中存储了一个加密密码。
我想通过使用指纹 API 对用户进行身份验证来解密该密码。
据我了解,我必须调用该FingerprintManager.authenticate(CryptoObject cryptoObject)
方法才能开始监听指纹结果。CryptoObject 参数的创建方式如下:
public static Cipher getDecryptionCipher(Context context) throws KeyStoreException {
try {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
SecretKey secretKey = getKeyFromKeyStore();
final IvParameterSpec ivParameterSpec = getIvParameterSpec(context);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
return cipher;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | IOException | UnrecoverableKeyException | CertificateException | InvalidAlgorithmParameterException | InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
Cipher cipher = FingerprintCryptoHelper.getDecryptionCipher(getContext());
FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
fingerprintManager.authenticate(cryptoObject, ...);
该方法在调用getDecryptionCipher()
之前正常工作。cipher.init()
在这个调用中,我得到一个UserNotAuthenticatedException
,因为用户没有通过这个 secretKey 的身份验证。这在某种程度上是有道理的。但这不是一个循环,不可能实现:
- 为了验证用户身份,我想使用他/她的指纹
- 为了听他/她的指纹,我需要初始化密码,作为回报,密码需要经过身份验证的用户
这里有什么问题??
编辑:
我使用模拟器(Nexus 4,API 23)。
这是我用来创建密钥的代码。
private SecretKey createKey() {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
keyGenerator.init(new KeyGenParameterSpec.Builder(
KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
return keyGenerator.generateKey();
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
throw new RuntimeException("Failed to create a symmetric key", e);
}
}