Как получить ключ из хранилища ключей при успешной аутентификации по отпечатку пальца
Я создаю приложение, в котором у пользователя есть две возможности разблокировать свое приложение: один использует пин-код, а другой - отпечаток пальца. Для использования отпечатка пальца они должны сначала установить пин-код, потому что этот пин-код является ключом дешифрования, чтобы получить их зашифрованные данные изSharedPreferences
.
Итак, я следовал этому уроку здесь:http://www.techotopia.com/index.php/An_Android_Fingerprint_Authentication_Tutorial#Accessing_the_Android_Keystore_and_KeyGenerator
Мне удалось заставить приложение прочитать отпечаток пальца и сказать, является ли оно действительным или нет. Но когда отпечаток авторизован, я понятия не имею, как вытащить этот пин из хранилища ключей Android.
Вот некоторый код для демонстрации:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
if (!keyguardManager.isKeyguardSecure()) {
Toast.makeText(this, "Lock screen security not enabled in Settings", Toast.LENGTH_LONG).show();
return;
}
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.USE_FINGERPRINT) !=
PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Fingerprint authentication permission not enabled", Toast.LENGTH_LONG).show();
return;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
// This happens when no fingerprints are registered.
Toast.makeText(this, "Register at least one fingerprint in Settings", Toast.LENGTH_LONG).show();
return;
}
generateKey();
if (cipherInit()) {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
protected void generateKey() {
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
} catch (Exception e) {
e.printStackTrace();
}
try {
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
throw new RuntimeException("Failed to get KeyGenerator instance", e);
}
try {
keyStore.load(null);
keyGenerator.init(new
KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
keyGenerator.generateKey();
} catch (NoSuchAlgorithmException |
InvalidAlgorithmParameterException
| CertificateException | IOException e) {
throw new RuntimeException(e);
}
}
public boolean cipherInit() {
try {
cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException |
NoSuchPaddingException e) {
throw new RuntimeException("Failed to get Cipher", e);
}
try {
keyStore.load(null);
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
null);
cipher.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);
}
}
KEY_NAME - это ключ (пин-код), который я пытаюсь сохранить (я думаю).
Тогда вFingerprintHandler
класс есть этот метод:
public void onAuthenticationSucceeded(
FingerprintManager.AuthenticationResult result) {
Toast.makeText(appContext,
"Authentication succeeded.",
Toast.LENGTH_LONG).show();
}
Но как мне получить ключ, который я хочу получить отresult
если вообще?