diff --git a/android/src/main/java/com/oblador/keychain/DeviceAvailability.java b/android/src/main/java/com/oblador/keychain/DeviceAvailability.java index 508ad4f..090d47b 100644 --- a/android/src/main/java/com/oblador/keychain/DeviceAvailability.java +++ b/android/src/main/java/com/oblador/keychain/DeviceAvailability.java @@ -10,15 +10,15 @@ public class DeviceAvailability { if (android.os.Build.VERSION.SDK_INT >= 23) { FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); - return fingerprintManager.isHardwareDetected() && + return fingerprintManager != null && fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints(); } return false; } - public static boolean isSecure(Context context) { + public static boolean isDeviceSecure(Context context) { KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); - return android.os.Build.VERSION.SDK_INT >= 23 && keyguardManager.isDeviceSecure(); + return Build.VERSION.SDK_INT >= 23 && keyguardManager != null && keyguardManager.isDeviceSecure(); } } diff --git a/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreAESCBC.java b/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreAESCBC.java index 8174ed9..40063dc 100644 --- a/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreAESCBC.java +++ b/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreAESCBC.java @@ -29,6 +29,7 @@ import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.spec.IvParameterSpec; +@TargetApi(Build.VERSION_CODES.M) public class CipherStorageKeystoreAESCBC implements CipherStorage { public static final String CIPHER_STORAGE_NAME = "KeystoreAESCBC"; public static final String DEFAULT_SERVICE = "RN_KEYCHAIN_DEFAULT_ALIAS"; @@ -52,7 +53,6 @@ public class CipherStorageKeystoreAESCBC implements CipherStorage { return Build.VERSION_CODES.M; } - @TargetApi(Build.VERSION_CODES.M) @Override public EncryptionResult encrypt(@NonNull String service, @NonNull String username, @NonNull String password) throws CryptoFailedException { service = getDefaultServiceIfEmpty(service); @@ -61,21 +61,7 @@ public class CipherStorageKeystoreAESCBC implements CipherStorage { KeyStore keyStore = getKeyStoreAndLoad(); if (!keyStore.containsAlias(service)) { - AlgorithmParameterSpec spec; - spec = new KeyGenParameterSpec.Builder( - service, - KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT) - .setBlockModes(ENCRYPTION_BLOCK_MODE) - .setEncryptionPaddings(ENCRYPTION_PADDING) - .setRandomizedEncryptionRequired(true) - //.setUserAuthenticationRequired(true) // Will throw InvalidAlgorithmParameterException if there is no fingerprint enrolled on the device - .setKeySize(ENCRYPTION_KEY_SIZE) - .build(); - - KeyGenerator generator = KeyGenerator.getInstance(ENCRYPTION_ALGORITHM, KEYSTORE_TYPE); - generator.init(spec); - - generator.generateKey(); + generateKeyAndStoreUnderAlias(service); } Key key = keyStore.getKey(service, null); @@ -93,6 +79,23 @@ public class CipherStorageKeystoreAESCBC implements CipherStorage { } } + private void generateKeyAndStoreUnderAlias(@NonNull String service) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { + AlgorithmParameterSpec spec = new KeyGenParameterSpec.Builder( + service, + KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT) + .setBlockModes(ENCRYPTION_BLOCK_MODE) + .setEncryptionPaddings(ENCRYPTION_PADDING) + .setRandomizedEncryptionRequired(true) + //.setUserAuthenticationRequired(true) // Will throw InvalidAlgorithmParameterException if there is no fingerprint enrolled on the device + .setKeySize(ENCRYPTION_KEY_SIZE) + .build(); + + KeyGenerator generator = KeyGenerator.getInstance(ENCRYPTION_ALGORITHM, KEYSTORE_TYPE); + generator.init(spec); + + generator.generateKey(); + } + @Override public DecryptionResult decrypt(@NonNull String service, @NonNull byte[] username, @NonNull byte[] password) throws CryptoFailedException { service = getDefaultServiceIfEmpty(service);