Browse Source

AES encryption added

master
Preyea Regmi 5 years ago
parent
commit
8f9c864b81
  1. 1
      app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrefKeys.java
  2. 28
      app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrivilegedGateway.java
  3. 3
      app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrivilegedGatewayInterface.java
  4. 2
      app/src/main/java/com/gmeremit/online/gmeremittance_native/changepasswordV2/presenter/ChangePasswordV2Presenter.java
  5. 153
      app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/presenter/LoginV2Presenter.java
  6. 8
      app/src/main/java/com/gmeremit/online/gmeremittance_native/settings/view/SettingsView.java
  7. 2
      app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/presenter/TransactionPasswordPromptV2Presenter.java
  8. 11
      app/src/main/java/com/gmeremit/online/gmeremittance_native/utils/security/SecurityUtils.java

1
app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrefKeys.java

@ -51,4 +51,5 @@ public class PrefKeys {
public static String APP_FINGER_PRINT_ENABLED ="APP_FINGER_PRINT_ENABLED";
public static String APP_USER_SECRET_KEY ="APP_USER_SECRET_KEY";
public static String APP_USER_ID_SECRET_KEY ="APP_USER_ID_KEY";
public static String APP_SECRET_KEY ="APP_SECRET_KEY";
}

28
app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrivilegedGateway.java

@ -6,6 +6,7 @@ import android.util.Log;
import com.gmeremit.online.gmeremittance_native.GmeApplication;
import com.gmeremit.online.gmeremittance_native.homeV2.model.UserInfoModelV2;
import com.gmeremit.online.gmeremittance_native.utils.security.SecurityUtils;
import static com.gmeremit.online.gmeremittance_native.base.PrefKeys.USER_PREFERRED_LOCALE;
@ -13,6 +14,7 @@ import static com.gmeremit.online.gmeremittance_native.base.PrefKeys.USER_PREFER
@SuppressWarnings("HardCodedStringLiteral")
public abstract class PrivilegedGateway implements PrivilegedGatewayInterface {
private static PrivilegedGatewayDataObserverManager privilegedGatewayDataObserverManager = null;
public interface PrivilegedGatewayDataObserver {
@ -135,15 +137,17 @@ public abstract class PrivilegedGateway implements PrivilegedGatewayInterface {
@SuppressLint("ApplySharedPref")
@Override
public void clearAllUserData() {
String persistedPwd=GmeApplication.getStorage().getString(PrefKeys.APP_USER_SECRET_KEY,null);
String persistedUserId=GmeApplication.getStorage().getString(PrefKeys.APP_USER_ID_SECRET_KEY,null);
boolean persistedFingerAuthEnabled=GmeApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,false);
String persistedPwd=getPersistedUserPwd();
String persistedUserId=getPersistedUserId();
String persistedSecretKey=getPersistedSecretKey();
boolean persistedFingerAuthEnabled=isFingerPrintAuthEnabled();
GmeApplication.getStorage().edit().clear().commit();
GmeApplication.getStorage().edit().putString(PrefKeys.APP_USER_ID_SECRET_KEY,persistedUserId).apply();
GmeApplication.getStorage().edit().putString(PrefKeys.APP_USER_SECRET_KEY,persistedPwd).apply();
GmeApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,persistedFingerAuthEnabled).apply();
persistUserId(persistedUserId);
persistUserPwd(persistedPwd);
persistSecretKey(persistedSecretKey);
turnOffFingerprintAuth(!persistedFingerAuthEnabled);
}
/**
@ -179,6 +183,12 @@ public abstract class PrivilegedGateway implements PrivilegedGatewayInterface {
}
@Override
public void persistSecretKey(String encrypted) {
Log.d(SecurityUtils.TAG,"To be Stored Key :"+encrypted);
GmeApplication.getStorage().edit().putString(PrefKeys.APP_SECRET_KEY,encrypted).apply();
}
@Override
public boolean isFingerPrintAuthEnabled() {
return GmeApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,false);
@ -196,6 +206,12 @@ public abstract class PrivilegedGateway implements PrivilegedGatewayInterface {
return GmeApplication.getStorage().getString(PrefKeys.APP_USER_SECRET_KEY,null);
}
@Override
public String getPersistedSecretKey() {
Log.d(SecurityUtils.TAG,"Stored Key :"+GmeApplication.getStorage().getString(PrefKeys.APP_SECRET_KEY,null));
return GmeApplication.getStorage().getString(PrefKeys.APP_SECRET_KEY,null);
}
@Override
public void turnOffFingerprintAuth(boolean action) {
GmeApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,!action).apply();

3
app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrivilegedGatewayInterface.java

@ -65,6 +65,7 @@ public interface PrivilegedGatewayInterface extends BaseGatewayInterface {
*/
void persistUserId(String encrypted);
void persistUserPwd(String encrypted);
void persistSecretKey(String encrypted);
boolean isFingerPrintAuthEnabled();
@ -72,6 +73,8 @@ public interface PrivilegedGatewayInterface extends BaseGatewayInterface {
String getPersistedUserPwd();
String getPersistedSecretKey();
void turnOffFingerprintAuth(boolean action);
void flushBiometricData();

2
app/src/main/java/com/gmeremit/online/gmeremittance_native/changepasswordV2/presenter/ChangePasswordV2Presenter.java

@ -174,7 +174,7 @@ public class ChangePasswordV2Presenter extends BasePresenter implements ChangePa
@Override
protected void onSuccess(ChangePasswordActivityV2APIResponse changePasswordActivityV2APIResponse) {
if (changePasswordActivityV2APIResponse.getErrorCode().equalsIgnoreCase(Constants.SUCCESS_CODE_V2)) {
if (SecurityUtils.doesAppHasBiometricFeature(view.getContext())) {
if (SecurityUtils.checkFingerPrintUsablity(view.getContext())) {
encryptPassword(newPassword, changePasswordActivityV2APIResponse.getMsg());
} else {
view.showPopUpMessage(changePasswordActivityV2APIResponse.getMsg(), CustomAlertDialog.AlertType.SUCCESS, alertType -> view.exitView());

153
app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/presenter/LoginV2Presenter.java

@ -1,7 +1,5 @@
package com.gmeremit.online.gmeremittance_native.loginV2.presenter;
import android.os.Build;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.util.Log;
import com.gmeremit.online.gmeremittance_native.GmeApplication;
@ -14,11 +12,7 @@ import com.gmeremit.online.gmeremittance_native.utils.Constants;
import com.gmeremit.online.gmeremittance_native.utils.Utils;
import com.gmeremit.online.gmeremittance_native.utils.https.GenericApiObserverResponse;
import com.gmeremit.online.gmeremittance_native.utils.security.SecurityUtils;
import com.mtramin.rxfingerprint.data.FingerprintAuthenticationException;
import com.mtramin.rxfingerprint.data.FingerprintDecryptionResult;
import com.mtramin.rxfingerprint.data.FingerprintEncryptionResult;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -53,21 +47,33 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
}
}
private void persistUserCredentialForBiometricAuth(String userId, String pwd) {
Observable.zip(Observable.just(userId), encryptData(pwd), BiometricEncParams::new)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiometricEncrypterObserver());
private void persistUserCredentialForFingerprintAuth(String userId, String pwd) {
SecurityUtils.generateKey()
.flatMap(key -> Observable.zip(Observable.just(userId),
SecurityUtils.encryptSymmetric(pwd, key).subscribeOn(Schedulers.io()),
encryptToKeyStore(key).subscribeOn(Schedulers.io()),
FingerprintEncResult::new)
).observeOn(AndroidSchedulers.mainThread())
.subscribe(new FingerprintEncResultObserver());
}
private Observable<FingerprintEncryptionResult> encryptData(String data) {
private Observable<String> encryptToKeyStore(String data) {
return SecurityUtils.encryptToKeyStore(view.getContext(), data)
.subscribeOn(Schedulers.io());
.flatMap(encKey -> Observable.just(encKey.getEncrypted()));
}
private Observable<FingerprintDecResult> authenticateFingerprint() {
return Observable.zip(Observable.fromCallable(gateway::getPersistedUserId),
Observable.fromCallable(gateway::getPersistedSecretKey)
.flatMap(storedKey -> decryptFromKeyStore(storedKey).flatMap(decAesKey -> SecurityUtils.decryptSymmetric(gateway.getPersistedUserPwd(), decAesKey)))
.subscribeOn(Schedulers.io()),
FingerprintDecResult::new)
.observeOn(AndroidSchedulers.mainThread());
}
private Observable<FingerprintDecryptionResult> decryptData(String data) {
private Observable<String> decryptFromKeyStore(String data) {
return SecurityUtils.decryptFromKeyStore(view.getContext(), data)
.subscribeOn(Schedulers.io())
.flatMap(authentication -> {
switch (authentication.getResult()) {
case FAILED:
@ -80,7 +86,8 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
return io.reactivex.Observable.error(new Throwable(authentication.getMessage()));
}
});
})
.map(FingerprintDecryptionResult::getDecrypted);
}
@ -102,7 +109,7 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
@Override
public boolean checkIfBiometricIsAvailable() {
return SecurityUtils.doesAppHasBiometricFeature(view.getContext()) && gateway.isFingerPrintAuthEnabled() && gateway.getPersistedUserId() != null && gateway.getPersistedUserPwd() != null;
return SecurityUtils.checkFingerPrintUsablity(view.getContext()) && gateway.isFingerPrintAuthEnabled() && gateway.getPersistedUserId() != null && gateway.getPersistedUserPwd() != null;
}
@Override
@ -115,29 +122,12 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
} else {
if (fingerPrintScanningSubscription == null || fingerPrintScanningSubscription.isDisposed())
view.showFingerPrintScanner(true);
fingerPrintScanningSubscription = Observable.zip(Observable.fromCallable(gateway::getPersistedUserId), decryptData(gateway.getPersistedUserPwd()), BiometricDecParams::new)
.observeOn(AndroidSchedulers.mainThread())
.retryWhen(errors -> errors.flatMap(
error -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && error instanceof KeyPermanentlyInvalidatedException) {
view.showFingerPrintScanner(false);
gateway.flushBiometricData();
}
else if(error instanceof FingerprintAuthenticationException)
{
view.showFingerPrintScanner(false);
}
else if (error instanceof SecurityUtils.FailedFingerPrintException || error instanceof SecurityUtils.SensorNotReadyException) {
view.showToastMessage(error.getMessage());
return Observable.timer(100, TimeUnit.MILLISECONDS);
}
return Observable.error(error);
}
))
.subscribeWith(new BiometricDecrypterObserver());
fingerPrintScanningSubscription = authenticateFingerprint()
.subscribeWith(new FingerprintDecResultObserver());
}
}
@Override
public void loginUser(String userId, String userPwd) {
String auth = "Basic " + Utils.toBase64("172017F9EC11222E8107142733:QRK2UM0Q:" + GmeApplication.getAppRelatedMetaData().getDeviceId());
@ -182,8 +172,8 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
@Override
protected void onSuccess(Boolean aBoolean) {
if (SecurityUtils.doesAppHasBiometricFeature(view.getContext()))
persistUserCredentialForBiometricAuth(userId, encUserPassword);
if (SecurityUtils.checkFingerPrintUsablity(view.getContext()))
persistUserCredentialForFingerprintAuth(userId, encUserPassword);
else {
view.showInvalidPassword(null);
view.showInvalidUserId(null);
@ -209,74 +199,85 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
}
}
public class BiometricEncParams {
private String userId;
private FingerprintEncryptionResult pwd;
BiometricEncParams(String userId, FingerprintEncryptionResult pwd) {
public class FingerprintEncResult {
String userId;
String encPwd;
String encKey;
public FingerprintEncResult(String userId, String encPwd, String encKey) {
this.userId = userId;
this.pwd = pwd;
this.encPwd = encPwd;
this.encKey = encKey;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
public String getEncPwd() {
return encPwd;
}
public FingerprintEncryptionResult getPwd() {
return pwd;
public String getEncKey() {
return encKey;
}
public void setPwd(FingerprintEncryptionResult pwd) {
this.pwd = pwd;
@Override
public String toString() {
return "FingerprintEncResult{" +
"userId='" + userId + '\'' +
", encPwd='" + encPwd + '\'' +
", encKey='" + encKey + '\'' +
'}';
}
}
public class BiometricDecParams {
private String userId;
private FingerprintDecryptionResult pwd;
public class FingerprintDecResult {
String userId;
String userPwd;
BiometricDecParams(String userId, FingerprintDecryptionResult pwd) {
public FingerprintDecResult(String userId, String userPwd) {
this.userId = userId;
this.pwd = pwd;
this.userPwd = userPwd;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public FingerprintDecryptionResult getPwd() {
return pwd;
public String getUserPwd() {
return userPwd;
}
public void setPwd(FingerprintDecryptionResult pwd) {
this.pwd = pwd;
@Override
public String toString() {
return "FingerprintDecResult{" +
"userId='" + userId + '\'' +
", userPwd='" + userPwd + '\'' +
'}';
}
}
public class BiometricEncrypterObserver extends DisposableObserver<BiometricEncParams> {
public class FingerprintEncResultObserver extends DisposableObserver<FingerprintEncResult> {
@Override
public void onNext(BiometricEncParams biometricParams) {
gateway.persistUserId(biometricParams.getUserId());
gateway.persistUserPwd(biometricParams.getPwd().getEncrypted());
public void onNext(FingerprintEncResult fingerprintEncResult) {
Log.d(SecurityUtils.TAG, "Success : " + fingerprintEncResult.toString());
gateway.persistSecretKey(fingerprintEncResult.getEncKey());
gateway.persistUserPwd(fingerprintEncResult.getEncPwd());
gateway.persistUserId(fingerprintEncResult.getUserId());
view.showInvalidPassword(null);
view.showInvalidUserId(null);
view.redirectToDashboard();
encUserPassword = null;
}
@Override
public void onError(Throwable e) {
Log.d(SecurityUtils.TAG,e.getMessage());
Log.d(SecurityUtils.TAG, "Failed : " + e.getMessage());
}
@Override
@ -285,19 +286,21 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
}
}
public class BiometricDecrypterObserver extends DisposableObserver<BiometricDecParams> {
public class FingerprintDecResultObserver extends DisposableObserver<FingerprintDecResult> {
@Override
public void onNext(BiometricDecParams biometricParams) {
encUserPassword = biometricParams.getPwd().getDecrypted();
view.onLoginPerformTask(() -> loginUser(biometricParams.getUserId(), ""));
public void onNext(FingerprintDecResult fingerprintDecResult) {
Log.d(SecurityUtils.TAG, "Success : " + fingerprintDecResult.toString());
encUserPassword = fingerprintDecResult.getUserPwd();
view.onLoginPerformTask(() -> loginUser(fingerprintDecResult.getUserId(), ""));
}
@Override
public void onError(Throwable e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && e instanceof KeyPermanentlyInvalidatedException)
return;
view.showToastMessage(e.getMessage());
Log.d(SecurityUtils.TAG, "Failed : " + e.getMessage());
}
@Override

8
app/src/main/java/com/gmeremit/online/gmeremittance_native/settings/view/SettingsView.java

@ -18,8 +18,6 @@ import com.gmeremit.online.gmeremittance_native.customwidgets.CustomAlertDialog;
import com.gmeremit.online.gmeremittance_native.settings.adapter.LanguageSelectionDialogRVAdapter;
import com.gmeremit.online.gmeremittance_native.splash_screen.model.LanguageModel;
import com.gmeremit.online.gmeremittance_native.utils.security.SecurityUtils;
import com.mtramin.rxfingerprint.data.FingerprintAuthenticationResult;
import com.mtramin.rxfingerprint.data.FingerprintEncryptionResult;
import java.util.ArrayList;
import java.util.List;
@ -27,11 +25,7 @@ import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import static com.gmeremit.online.gmeremittance_native.base.PrefKeys.USER_PREFERRED_COUNTRY_CODE;
import static com.gmeremit.online.gmeremittance_native.base.PrefKeys.USER_PREFERRED_LANGUAGE;
@ -59,7 +53,7 @@ public class SettingsView extends BaseActivity implements CompoundButton.OnCheck
private void init() {
ButterKnife.bind(this);
if (!SecurityUtils.doesAppHasBiometricFeature(this)) {
if (!SecurityUtils.checkFingerPrintUsablity(this)) {
view_fingerprint.setVisibility(View.GONE);
view_fingerprint_divider.setVisibility(View.GONE);
} else {

2
app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/presenter/TransactionPasswordPromptV2Presenter.java

@ -95,7 +95,7 @@ public class TransactionPasswordPromptV2Presenter extends BasePresenter implemen
@Override
public boolean checkIfUserHasEnabledBiometricAuth() {
return SecurityUtils.doesAppHasBiometricFeature(view.getContext()) && gateway.isFingerPrintAuthEnabled() && gateway.getPersistedUserId() != null && gateway.getPersistedUserPwd() != null;
return SecurityUtils.checkFingerPrintUsablity(view.getContext()) && gateway.isFingerPrintAuthEnabled() && gateway.getPersistedUserId() != null && gateway.getPersistedUserPwd() != null;
}

11
app/src/main/java/com/gmeremit/online/gmeremittance_native/utils/security/SecurityUtils.java

@ -17,7 +17,7 @@ public class SecurityUtils {
private static final String KEY_STORE_SECRET_ALIAS = "gmeSecret321";
private static String algorithm = "AES";
public static boolean doesAppHasBiometricFeature(Context context) {
public static boolean checkFingerPrintUsablity(Context context) {
return RxFingerprint.isAvailable(context);
}
@ -33,21 +33,20 @@ public class SecurityUtils {
return RxFingerprint.authenticate(context);
}
public static Observable<String> encryptSymmetric(String plainText, String key) throws Exception {
public static Observable<String> encryptSymmetric(String plainText, String key) {
return Observable.fromCallable(() -> AESEncryptionHelper.encrypt(plainText, AESEncryptionHelper.keys(key)).toString());
}
public static Observable<String> decryptSymmetric(String encryptedText, String keys) throws Exception {
public static Observable<String> decryptSymmetric(String encryptedText, String keys){
return Observable.fromCallable(() -> {
AESEncryptionHelper.CipherTextIvMac cipherTextIvMac = new AESEncryptionHelper.CipherTextIvMac(encryptedText);
return AESEncryptionHelper.decryptString(cipherTextIvMac, AESEncryptionHelper.keys(keys));
});
}
//generateKey() is used to generate a secret key for AES algorithm
private static String generateKey() throws Exception {
return AESEncryptionHelper.keyString(AESEncryptionHelper.generateKey());
public static Observable<String> generateKey() {
return Observable.fromCallable(()->AESEncryptionHelper.keyString(AESEncryptionHelper.generateKey()));
}

Loading…
Cancel
Save