|
|
@ -10,6 +10,28 @@ import com.mtramin.rxfingerprint.data.FingerprintEncryptionResult; |
|
|
|
|
|
|
|
import io.reactivex.Observable; |
|
|
|
|
|
|
|
/** |
|
|
|
* Since we are using security keypad with Symmetric Key Encryption, we can only obtain encrypted text as password but not plain text. |
|
|
|
* So the length of the encrypted text exceeds 256 bit and we cannot use Public/Private Encryption Algorithm i.e. RSA encryption offfered by Android's KeyStore. |
|
|
|
* Therefore inorder to persist password and encryption key in same storage using Android's Keystore mechanism, we follow the following steps |
|
|
|
* 1) We generate AES key seperately using "AESEncryptionHelper" class if not already generated intially. |
|
|
|
* 2) Encrypt the confidential content with the AES Algorithm using the generated AES key and persist it. |
|
|
|
* 3) That AES key is then encrypted using RSA key provided by Keystore and persist it to prevent from being exploited. |
|
|
|
* |
|
|
|
* So we can store the encryption key and encrypted data in same persistence storage without any risk. |
|
|
|
* |
|
|
|
* Flow Illustration for Encryption is shown below, Decryption is done in same flow but in reverse order. |
|
|
|
* |
|
|
|
* Generated_AES_Key= GENERATE_NEW_AES_KEY(); |
|
|
|
* Encrypted_Password = AES_ENCRYPTION_USING_GENERATED_KEY(Generated_AES_Key, Long_Password_String); |
|
|
|
* SAVE_TO_DISK(Encrypted_Password); |
|
|
|
* |
|
|
|
* Encrypted_AES_KEY = RSA_ENCRYPTION_USING_KEYSTORE(Generated_AES_Key) |
|
|
|
* SAVE_TO_DISK(Encrypted_AES_KEY); |
|
|
|
* |
|
|
|
* Hence, we can persist both the key and encrypted data in same place with help of Android Key Store. |
|
|
|
* |
|
|
|
*/ |
|
|
|
|
|
|
|
public class SecurityUtils { |
|
|
|
|
|
|
@ -21,30 +43,63 @@ public class SecurityUtils { |
|
|
|
return RxFingerprint.isAvailable(context); |
|
|
|
} |
|
|
|
|
|
|
|
public static Observable<FingerprintEncryptionResult> encryptToKeyStore(Context context, String secret) { |
|
|
|
/** |
|
|
|
* Consider reading this helper class purpose before using this method. |
|
|
|
* @param context |
|
|
|
* @param secret String to be encrypted. |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public static Observable<FingerprintEncryptionResult> encryptUsingKeyStore(Context context, String secret) { |
|
|
|
return RxFingerprint.encrypt(EncryptionMethod.RSA, context, KEY_STORE_SECRET_ALIAS, secret); |
|
|
|
} |
|
|
|
|
|
|
|
public static Observable<FingerprintDecryptionResult> decryptFromKeyStore(Context context, String secret) { |
|
|
|
/** |
|
|
|
* Consider reading this helper class purpose before using this method. |
|
|
|
* @param context |
|
|
|
* @param secret |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public static Observable<FingerprintDecryptionResult> decryptUsingKeyStore(Context context, String secret) { |
|
|
|
return RxFingerprint.decrypt(EncryptionMethod.RSA, context, KEY_STORE_SECRET_ALIAS, secret); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Consider reading this helper class purpose before using this method. |
|
|
|
* @param context |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public static Observable<FingerprintAuthenticationResult> authenticateFingerPrint(Context context) { |
|
|
|
return RxFingerprint.authenticate(context); |
|
|
|
} |
|
|
|
|
|
|
|
public static Observable<String> encryptSymmetric(String plainText, String key) { |
|
|
|
/** |
|
|
|
* Consider reading this helper class purpose before using this method. |
|
|
|
* @param plainText String to be encrypted |
|
|
|
* @param key AES symmetric key |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public static Observable<String> encryptUsingAES(String plainText, String key) { |
|
|
|
return Observable.fromCallable(() -> AESEncryptionHelper.encrypt(plainText, AESEncryptionHelper.keys(key)).toString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public static Observable<String> decryptSymmetric(String encryptedText, String keys){ |
|
|
|
/** |
|
|
|
* Consider reading this helper class purpose before using this method. |
|
|
|
* @param encryptedText Encrypted data to be decrypted |
|
|
|
* @param key AES symmetric key |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public static Observable<String> decryptUsingAES(String encryptedText, String key){ |
|
|
|
return Observable.fromCallable(() -> { |
|
|
|
AESEncryptionHelper.CipherTextIvMac cipherTextIvMac = new AESEncryptionHelper.CipherTextIvMac(encryptedText); |
|
|
|
return AESEncryptionHelper.decryptString(cipherTextIvMac, AESEncryptionHelper.keys(keys)); |
|
|
|
return AESEncryptionHelper.decryptString(cipherTextIvMac, AESEncryptionHelper.keys(key)); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Generate AES Symmetric Key |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public static Observable<String> generateKey() { |
|
|
|
return Observable.fromCallable(()->AESEncryptionHelper.keyString(AESEncryptionHelper.generateKey())); |
|
|
|
} |
|
|
|