diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 0685cba4..13a19c8e 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser index bd906323..f7998ae1 100644 Binary files a/.idea/caches/gradle_models.ser and b/.idea/caches/gradle_models.ser differ diff --git a/app/src/main/java/com/gmeremit/online/gmeremittance_native/base/BaseActivity.java b/app/src/main/java/com/gmeremit/online/gmeremittance_native/base/BaseActivity.java index 52bc5658..6c60af8a 100644 --- a/app/src/main/java/com/gmeremit/online/gmeremittance_native/base/BaseActivity.java +++ b/app/src/main/java/com/gmeremit/online/gmeremittance_native/base/BaseActivity.java @@ -2,11 +2,14 @@ package com.gmeremit.online.gmeremittance_native.base; import android.app.Activity; import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v4.app.FragmentManager; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; +import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.Toast; @@ -19,6 +22,16 @@ public class BaseActivity extends AppCompatActivity implements BaseContractInter private boolean isProgressBarShowing; private CustomAlertDialog customAlertDialog; + private boolean shouldEnableAppScreenShot=false; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if(!shouldEnableAppScreenShot) { + getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); + } + } + @Override public void showProgressBar(boolean action, String message) { try { @@ -46,6 +59,11 @@ public class BaseActivity extends AppCompatActivity implements BaseContractInter } + protected void enableAppToTakeScreenShot(boolean action) + { + this.shouldEnableAppScreenShot=action; + } + @Override public void showPopUpMessage(String message, CustomAlertDialog.AlertType alertType, CustomAlertDialog.CustomDialogActionListener listener) { try { diff --git a/app/src/main/java/com/gmeremit/online/gmeremittance_native/splash_screen/view/SplashScreen.java b/app/src/main/java/com/gmeremit/online/gmeremittance_native/splash_screen/view/SplashScreen.java index ccb6f1e0..13c22af2 100644 --- a/app/src/main/java/com/gmeremit/online/gmeremittance_native/splash_screen/view/SplashScreen.java +++ b/app/src/main/java/com/gmeremit/online/gmeremittance_native/splash_screen/view/SplashScreen.java @@ -10,6 +10,7 @@ import android.support.v4.content.ContextCompat; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.text.Html; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -24,6 +25,7 @@ import com.gmeremit.online.gmeremittance_native.loginV2.view.LoginV2Activity; import com.gmeremit.online.gmeremittance_native.registerV2.view.RegisterV2Activity; import com.gmeremit.online.gmeremittance_native.utils.KeyboardUtils; import com.gmeremit.online.gmeremittance_native.utils.other.PersistenceStorageManager; +import com.gmeremit.online.gmeremittance_native.utils.security.SignatureCheck; import com.scottyab.rootbeer.RootBeer; import butterknife.BindView; @@ -152,18 +154,18 @@ public class SplashScreen extends BaseActivity { protected void onResume() { super.onResume(); startAntiDebugger(); - if (rootBeer.isRootedWithoutBusyBoxCheck()) { - showPopUpMessage("Rooted devices are not supported", CustomAlertDialog.AlertType.ALERT, null); - new Handler().postDelayed(this::finish, 2000); - } else { - //we didn't find indication of root + if(!rootBeer.isRootedWithoutBusyBoxCheck()&&checkIfAppSafe()) + { if (persistenceStorageManager.getLoggedin() != null && persistenceStorageManager.getLoggedin().equals("HOME")) { startActivity(new Intent(this, HomeActivityV2.class)); finish(); } } - - + else + { + showPopUpMessage("Invalid app", CustomAlertDialog.AlertType.ALERT, null); + new Handler().postDelayed(this::finish, 2000); + } } @Override @@ -206,6 +208,16 @@ public class SplashScreen extends BaseActivity { } } + private boolean checkIfAppSafe() { + boolean isSafe = false; + try { + isSafe = new SignatureCheck().validateAppSignature(this); + } catch (Exception e) { + e.printStackTrace(); + isSafe = false; + } + return isSafe; + } public native void antiDebugCheck(); diff --git a/app/src/main/java/com/gmeremit/online/gmeremittance_native/utils/security/SignatureCheck.java b/app/src/main/java/com/gmeremit/online/gmeremittance_native/utils/security/SignatureCheck.java new file mode 100644 index 00000000..4e00a060 --- /dev/null +++ b/app/src/main/java/com/gmeremit/online/gmeremittance_native/utils/security/SignatureCheck.java @@ -0,0 +1,69 @@ +package com.gmeremit.online.gmeremittance_native.utils.security; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; + +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.Signature; +import android.util.Log; + + +public class SignatureCheck { + + //we store the hash of the signture for a little more protection + private static final String APP_SIGNATURE = "A4BB8351A51F950F74CF6B42A6C5C90971C2B36A"; + + /** + * Query the signature for this application to detect whether it matches the + * signature of the real developer. If it doesn't the app must have been + * resigned, which indicates it may been tampered with. + * + * @param context + * @return true if the app's signature matches the expected signature. + * @throws NameNotFoundException + */ + public boolean validateAppSignature(Context context) throws Exception { + + PackageInfo packageInfo = context.getPackageManager().getPackageInfo( + context.getPackageName(), PackageManager.GET_SIGNATURES); + //note sample just checks the first signature + for (Signature signature : packageInfo.signatures) { + // SHA1 the signature + + String sha1 = getSHA1(signature.toByteArray()); + // check is matches hardcoded value + Log.d("SignatureHash","Sha: "+sha1); + return APP_SIGNATURE.equals(sha1); + } + + return false; + } + + //computed the sha1 hash of the signature + public static String getSHA1(byte[] sig) throws NoSuchProviderException, NoSuchAlgorithmException { + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.update(sig); + byte[] hashtext = digest.digest(); + return bytesToHex(hashtext); + } + + //util method to convert byte array to hex string + public static String bytesToHex(byte[] bytes) { + final char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + char[] hexChars = new char[bytes.length * 2]; + int v; + for (int j = 0; j < bytes.length; j++) { + v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + +}