I\'m following the ConfirmCredential Android example provided by Google, but it only shows how to encrypt the data. When I try to decrypt it I get exception:
ja
I created an issue in the github project for the sample provided by google (link to the issue here). The response I got is that I must use the IV that was generated when the value was encrypted. (same as in the solution provided by @Qianqian)
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(encryptCipher.getIV()));
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
I created a sample application that shows how to do this. It is available on github, here.
Hope this is useful to someone.
Basically you have to pass the IvParameterSpec for the decrypt mode whereas you should not manually set it for encryption mode.
So here is what I did and it worked well:
private initCipher(int mode) {
try {
byte[] iv;
mCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
IvParameterSpec ivParams;
if(mode == Cipher.ENCRYPT_MODE) {
mCipher.init(mode, generateKey());
ivParams = mCipher.getParameters().getParameterSpec(IvParameterSpec.class);
iv = ivParams.getIV();
fos = getContext().openFileOutput(IV_FILE, Context.MODE_PRIVATE);
fos.write(iv);
fos.close();
}
else {
key = (SecretKey)keyStore.getKey(KEY_NAME, null);
File file = new File(getContext().getFilesDir()+"/"+IV_FILE);
int fileSize = (int)file.length();
iv = new byte[fileSize];
FileInputStream fis = getContext().openFileInput(IV_FILE);
fis.read(iv, 0, fileSize);
fis.close();
ivParams = new IvParameterSpec(iv);
mCipher.init(mode, key, ivParams);
}
mCryptoObject = new FingerprintManager.CryptoObject(mCipher);
} catch(....)
}
You can also encode the IV data with Base64 and save it under shared preferences instead of saving it under a file.
In either case, If you have employed the new full backup feature for Android M, keep in mind that this data should NOT be allowed to backup/restore since it is invalid when a user reinstall the app or install the app on another device.
How about this,
mCipher.init(Cipher.DECRYPT_MODE, key, mCipher.getParameters());
If you use the sample code from Google repo, above line will work, also note, for every mChiper.init we need to authenticate with fingerprint once, that means two fingerprint auth is required, one for encryption and one for decryption.
https://github.com/googlesamples/android-FingerprintDialog