I. Introduction
Android in the development process, are generally not too focused on security vulnerabilities app unless the app so some companies experiencing high demand or have to provide a means for detecting the app for testing, but testing and strengthening cost is relatively high, it is ignored the problem, but I recently did the app higher level of security, there will be more security agencies after detecting a problem, by the way there are a lot of testing organizations, such as 360, Blue Shield, Bang Bang and so on.
Second, the problem summary
Application Signature not verified risk | high | Join signature verification |
Backup application data from any risks | in | Join android in Androidmaifest.xml in: allowBackup = "false" |
Clipboard sensitive information disclosure vulnerability | in | Has been removed |
HTTPS does not validate the server's certificate Vulnerability | in | The program has been configured server certificates vulnerability |
HTTPS does not check hostname vulnerability | in | The program has been configured HTTPS not check hostname vulnerability |
Webview loopholes to bypass the certificate verification | in | Can not be bypassed |
Screenshot attack risk | in | Screenshot function has banned the landing page and other major home page |
Keyboard input monitoring risk | High-risk | Third-party reinforcement |
Java code decompile risk | [High-risk] | Third-party reinforcement |
Activity interface hijacking | [In danger] | Rewrite omKeyDown methods and methods onPause |
Third, problem solving
1, the application does not check the signature risk
Solution: Join signature verification
Add the following code in an initial change in the activity
//验证签名是否正确
SignTool.CheckSign(InitActivity.this);
SignTool class implementation code:
import java.security.MessageDigest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
/** Tool.java: ----- 2018-12-28 下午4:04:54 scimence
* 1、获取签名信息 getSignature()
* 2、检测签名信息 CheckSign() */
public class SignTool {
/** 检测当前应用的签名信息,若不相同则自动退出 */
public static void CheckSign(Activity activity)
{
String sign = getSignature(activity);
if (!sign.equals("4e98e3f2faa93b0222ecddce420ff94b")) // 修改此处值为游戏包对应签名
{
activity.finish();
System.exit(0); // 退出运行
}
}
/** 获取应用的签名信息 */
public static String getSignature(Context context)
{
String packageName = getPackageName(context);
String sign = getSign(context, packageName);
return sign;
}
/** 获取acitivty所在的应用包名 */
public static String getPackageName(Context activity)
{
ApplicationInfo appInfo = activity.getApplicationInfo();
String packageName = appInfo.packageName; // 获取当前游戏安装包名
return packageName;
}
/** 获取包名对应应用的签名信息 */
public static String getSign(Context paramContext, String packageName)
{
String S = "";
try
{
byte[] array = null;
PackageInfo localPackageInfo = paramContext.getPackageManager().getPackageInfo(packageName, 64);
for (int i = 0; i < localPackageInfo.signatures.length; i++)
{
array = localPackageInfo.signatures[i].toByteArray();
if (array != null) break;
}
S = MD5(array);
}
catch (Exception ex)
{
}
return S;
}
/** 计算MD5值 */
public static String MD5(String data)
{
try
{
String str = MD5(data.getBytes());
return str;
}
catch (Exception ex)
{}
return null;
}
/** 计算MD5值 */
public static String MD5(byte[] data)
{
try
{
// 获取data的MD5摘要
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// mdInst.update(content.getBytes());
mdInst.update(data);
byte[] md = mdInst.digest();
// 转换为十六进制的字符串形式
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < md.length; i++)
{
String shaHex = Integer.toHexString(md[i] & 0xFF);
if (shaHex.length() < 2)
{
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
2, screenshots attack risk
Add the following code to prevent activity or activity screenshot cited:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,WindowManager.LayoutParams.FLAG_SECURE);
3, Activity interface hijacking
Rewrite onkeydown and onpase method, when the screen is blocked, pop-up message
public boolean onKeyDown(int keyCode, KeyEvent event) {
if((keyCode==KeyEvent.KEYCODE_BACK || keyCode==KeyEvent.KEYCODE_HOME) && event.getRepeatCount()==0){
//加的人保健康
Log.i("feng",this.myWebView.getUrl());
needAlarm = false;
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
@Override
public void onPause() {
//若程序进入后台不是用户自身造成的,则需要弹出警示
if(needAlarm) {
//弹出警示信息
Toast.makeText(getApplicationContext(), "您的界面已运行在后台,请确认环境是否安全", Toast.LENGTH_SHORT).show();
//启动我们的AlarmService,用于给出覆盖了正常Activity的类名
// Intent intent = new Intent(this, AlarmService.class);
// startService(intent);
}
super.onPause();
}
IV Summary
In fact, this is just basic security policy ultimately requires third-party software can be reinforced to ensure the app is not decompiled.