增強APP的安全性(一)

增強APP的安全性(一)–通過檢查APP信息

前言

當我們發佈一款新的APP的時候,最不願看到的是我們的成果被別人竊取,所以如何提高我們APP的安全性在開發過程中也是非常重要的。常見增強安全性的手段有很多。例如:混淆Java代碼、用C/C++實現關鍵代碼、APK加固等等。今天我介紹的是可以迅速添加到項目中的來增強APP安全的方式。

通過檢查APP信息來增強APP的安全性

具體代碼如下:

package com.dong.mobilesafe.utils.security;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Created by Jesse on 2016/6/13 0013.
 */
public class SecurityCheckManager {
    public static int SIG_HASH_CODE = -2057429939;
    private static SecurityCheckManager instance;


    private SecurityCheckManager() {
    }

    public static SecurityCheckManager getInstance() {
        if (instance == null) {
            synchronized (SecurityCheckManager.class) {
                if (instance == null) {
                    instance = new SecurityCheckManager();
                }
            }
        }
        return instance;
    }


    /**
     * 是否運行在模擬器中
     *
     * @return true表示運行在模擬器中,否則運行在真機中
     */
    private boolean isRunningInEmulator() {
        boolean qemuKernel = false;
        Process process = null;
        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec("getprop ro.kernel.qemu");
            os = new DataOutputStream(process.getOutputStream());
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            os.flush();
            process.waitFor();
            qemuKernel = (Integer.valueOf(in.readLine()) == 1);
        } catch (Exception e) {
            qemuKernel = false;
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (process != null) {
                    process.destroy();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return qemuKernel;
    }


    /**
     * 檢查簽名是否有誤,防止惡意修改簽名
     *
     * @return true簽名有誤,否則簽名正確
     */
    private boolean isSignatureError(Context context) {
        boolean isError = false;
        PackageManager packageManager = context.getPackageManager();
        try {
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(),PackageManager.GET_SIGNATURES);
            Signature[] signatures = packageInfo.signatures;
            int sig = signatures[0].hashCode();
            if(sig != SIG_HASH_CODE) {
                isError = true;
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return isError;
    }

    /**
     * 檢查軟件是否可以調試
     * @return
     */
    private boolean isDebuggable(Context context) {
        boolean debuggable = false;
        if((context.getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            debuggable = true;
        }
        return debuggable;
    }


    /**
     * 對APP進行安全檢查,如果發現運行在模擬器上、簽名被修改和應用能夠被調試
     * 則程序會自動關閉
     * @param context
     */
    public void securityCheck(final Context context) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                // Moves the current Thread into the background
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
                if(isRunningInEmulator()) {
                    killMyself();
                    return;
                }
                if(isSignatureError(context)) {
                    killMyself();
                    return;
                }
                if(isDebuggable(context)) {
                    killMyself();
                    return;
                }
            }
        };
        new Thread(r).start();
    }


    /**
     * 殺死自己的進程
     */
    private void killMyself() {
        android.os.Process.killProcess(android.os.Process.myPid());
    }




}

然後我們在APP啓動的地方添加如下代碼:

public class SecurityApplication extends Application{
    public boolean isReleaseVersion = true;
    private static SecurityApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        if(isReleaseVersion) {
            SecurityCheckManager.getInstance().securityCheck(this);
        }
        ....
    }

    public static SecurityApplication getInstance() {
        return instance;
    }
}

通過上面的步驟就可以來增強我們app的安全性,當然這些手段對於一些專業破解APP的人來說也是很容易破解的。但是這種方式好處是簡單,只要增加幾行代碼。當然的最好的手段是通過一系列的手段來增強APP的安全性,如結合我上面提到的手段結合在一起來提高破解的難度。下一篇我們開始學習混淆的方式來增強APP的安全性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章