Skip to content

Instantly share code, notes, and snippets.

@MiguelCatalan
Last active November 6, 2015 12:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MiguelCatalan/b4f1e30cb96dc1e19185 to your computer and use it in GitHub Desktop.
Save MiguelCatalan/b4f1e30cb96dc1e19185 to your computer and use it in GitHub Desktop.
public class SecurityWard {
private static final String CLASS_TAG = "SecurityWard";
private static final String CERTIFICATE_SHA1 = "";
/**
* Detect if Google Play Store was the installer
* @param context Current context
* @return true if was installed with Google Play Store
*/
public static boolean checkGooglePlayStore (Context context) {
String installerPackageName = context.getPackageManager().getInstallerPackageName(context.getPackageName());
return installerPackageName != null && installerPackageName.startsWith("com.google.android");
}
/**
* Detect if it runs on an emulator
* @return true if the app it's running on a emulator
*/
public static boolean isEmulator(){
try {
Class systemPropetyClazz = Class.forName("android.os.SystemProperties");
boolean kernelQemu = getProperty(systemPropetyClazz, "ro.kernel.qemu").length() > 0 ;
boolean hardwareGoldfish = getProperty(systemPropetyClazz, "ro.hardware").equals("goldfish");
boolean modelSdk = getProperty(systemPropetyClazz, "ro.product.model").equals("sdk");
if (kernelQemu || hardwareGoldfish || modelSdk){
return true;
}
} catch (Exception e) {
LogManager.log(LogManager.ERROR,CLASS_TAG,"isEmulator",e.toString());
}
return false;
}
private static String getProperty (Class clazz, String propertyName) throws Exception {
return (String) clazz.getMethod("get", new Class[] {String.class}).invoke(clazz, new Object[] {propertyName});
}
/**
* Detect if the app has the debuggable flag enabled
* @param context Current context
* @return true if it's enabled
*/
public static boolean isDebuggable (Context context){
return (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
}
/**
* Detects if the current signature matches the original one
* @param context Current context
* @return true if the signatures match each other
*/
public static boolean validateAppSignature(Context context) {
try {
//get the signature from the package manager
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
Signature[] appsSignatures = packageInfo.signatures;
//this sample only checks the first certificate
for (Signature signature : appsSignatures){
byte[] singnatureBytes = signature.toByteArray();
//calc sha1 in hex
String currentSignature = calcSHA1(singnatureBytes);
//compare signatures
return CERTIFICATE_SHA1.equalsIgnoreCase(currentSignature);
}
}catch (Exception e){
LogManager.log(LogManager.ERROR,CLASS_TAG,"validateAppSignature",e.toString());
}
return false;
}
private static String calcSHA1(byte[] signature) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA1");
digest.update(signature);
byte[] signatureHash = digest.digest();
return bytesToHex(signatureHash);
}
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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment