Android apk完整性檢測(cè)的實(shí)現(xiàn)思路和代碼實(shí)現(xiàn)
需求和背景
行業(yè)相關(guān),對(duì)安全性較高的程序一般都需要添加完整性檢測(cè)的功能,以防止程序被篡改,從而導(dǎo)致安全問(wèn)題的發(fā)生。
相關(guān)的支付應(yīng)用項(xiàng)目今年也做了好幾個(gè),這些程序也都已通過(guò)了行業(yè)相關(guān)安全標(biāo)準(zhǔn)的認(rèn)證。
實(shí)現(xiàn)
下面來(lái)分享Android APP完整性校驗(yàn)的實(shí)現(xiàn)思路和代碼實(shí)現(xiàn)。
通過(guò)sp判斷當(dāng)前是否是第一次安裝apk,第一次安裝默認(rèn)apk是從市場(chǎng)下載安裝,默認(rèn)認(rèn)為是沒(méi)有被篡改過(guò)的??梢圆挥脵z查,只計(jì)算當(dāng)前的hash值并保存到文件中。
可以在application中執(zhí)行,計(jì)算apk的hash值并寫文件的操作是耗時(shí)操作,記得開子線程進(jìn)行。
private boolean integrityCheckResult = false; private boolean isFirstRun;//可以通過(guò)文件保存,例如SP @Override public void onCreate() { super.onCreate(); ThreadPoolManager.getInstance().runInBackground(new Runnable() { @Override public void run() { //檢測(cè)apk完整性 if (isFirstRun){//skip and calculate apk's hash SecurityManager.getInstance().checkIntegrity(true); integrityCheckResult = true; }else { integrityCheckResult = SecurityManager.getInstance().checkIntegrity(false); } } }); public boolean isIntegrityCheckResult() { return integrityCheckResult; }
在入口activity中判斷是否完整性校驗(yàn)通過(guò),假如不通過(guò),可以彈窗提示然后鎖定APP,讓用戶重新在安全的平臺(tái)重新下載安裝。當(dāng)前APP無(wú)法使用,存在安全問(wèn)題。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (App.getApp().isIntegrityCheckResult()) { Log.d(TAG, "onCreate: checkIntegrity success"); } else { Log.d(TAG, "onCreate: checkIntegrity failed"); } }
安全管理類
新建一個(gè)安全管理類,用于管理所有和安全相關(guān)的類
public class SecurityManager { //做一個(gè)單例 private static SecurityManager instance = null; private final Integrity integrity; private SecurityManager(){ integrity = new Integrity(); } public static synchronized SecurityManager getInstance() { if (instance == null) instance = new SecurityManager(); return instance; } public boolean checkIntegrity(boolean isFirstInstall) { return integrity.checkIntegrity(isFirstInstall); } }
實(shí)現(xiàn)完整性檢測(cè)類的接口
public interface IIntegrity { boolean checkApkIntegrity(); }
完整性檢測(cè)實(shí)現(xiàn)類:
public class Integrity implements IIntegrity { public boolean checkIntegrity(boolean isFirstInstall) { if (isFirstInstall) { calcAndSaveApkSoHash(); return true; } else { return compareHashsWithLastTime(); } } private void calcAndSaveApkSoHash() { File apk = new File(BaseApplication.getAppContext().getPackageCodePath()); byte[] apkHash = HashCalculator.calculateHashBytes(apk, HashCalculator.SHA_256); FileUtils.writeBytesToFile(filePath + APK_HASH_FILE, apkHash); } private boolean compareHashsWithLastTime() { //檢測(cè)apk so return checkApkIntegrity(); } @Override public boolean checkApkIntegrity() { if (BuildConfig.DEBUG) { Log.w(TAG, "Debug version,skip apk‘s hash verification"); return true; } try { String apkPath = BaseApplication.getAppContext().getPackageCodePath(); byte[] originalApkHash = FileUtils.readFileToBytes(filePath + APK_HASH_FILE); return calcSrcAndCompareWithLastHash(originalApkHash, new File(apkPath)); } catch (IOException e) { Log.e(TAG, "checkApkAndLibs: ", e); } return false; } /** * 計(jì)算明文數(shù)據(jù)并和上一次hash進(jìn)行比較 * * @param decHashBytes 明文hash數(shù)據(jù) * @param decSrc 明文源數(shù)據(jù) */ private static boolean calcSrcAndCompareWithLastHash(byte[] decHashBytes, File decSrc) { String decHash = Utils.bcd2Str(decHashBytes); //計(jì)算解密ksn的hash String calcHash = HashCalculator.calculateHash(decSrc, HashCalculator.SHA_256); LogUtils.i(TAG, "calculate hash = " + Utils.bcd2Str( HashCalculator.calculateHashBytes(decSrc, HashCalculator.SHA_256))); return decHash.equalsIgnoreCase(calcHash); } }
相關(guān)工具類
這個(gè)只是工具類,方便獲取Application ,只要獲取context即可,可以隨意發(fā)揮。
public class BaseApplication extends Application { private static BaseApplication mBaseApplication ; mBaseApplication = this; } public static BaseApplication getAppContext(){ return mBaseApplication; }
編碼轉(zhuǎn)換工具:
@NonNull public static String bcd2Str(@Nullable byte[] b, int length) { if (b == null) { return ""; } StringBuilder sb = new StringBuilder(length * 2); for (int i = 0; i < length; ++i) { sb.append(ARRAY_OF_CHAR[((b[i] & 0xF0) >>> 4)]); sb.append(ARRAY_OF_CHAR[(b[i] & 0xF)]); } return sb.toString(); }
hash計(jì)算器
@NonNull public static String bcd2Str(@Nullable byte[] b, int length) { if (b == null) { return ""; } StringBuilder sb = new StringBuilder(length * 2); for (int i = 0; i < length; ++i) { sb.append(ARRAY_OF_CHAR[((b[i] & 0xF0) >>> 4)]); sb.append(ARRAY_OF_CHAR[(b[i] & 0xF)]); } return sb.toString(); }
文件工具類
/** * 文件鎖定(File Locking) * 強(qiáng)制刷新緩沖(Force Flushing Buffer): */ public static boolean writeBytesToFile(String filePath, byte[] bytes) { try (FileOutputStream fos = new FileOutputStream(filePath)) { fos.write(bytes); // 獲取文件鎖定 FileChannel fileChannel = fos.getChannel(); try (FileLock fileLock = fileChannel.lock()) { // 強(qiáng)制刷新緩沖 fileChannel.force(true); } return true; } catch (IOException e) { LogUtils.e(e); return false; } }
到此這篇關(guān)于Android apk完整性檢測(cè)的實(shí)現(xiàn)思路和實(shí)現(xiàn)過(guò)程全記錄的文章就介紹到這了,更多相關(guān)Android apk完整性檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flutter實(shí)現(xiàn)仿京東商品詳情底部操作欄
這篇文章主要為大家詳細(xì)介紹了Flutter如何仿京東實(shí)現(xiàn)商品詳情底部操作欄,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下2023-06-06android開發(fā)教程之startActivityForResult使用方法
這篇文章主要介紹了android開發(fā)教程之startActivityForResult使用方法,需要的朋友可以參考下2014-03-032021最新Android筆試題總結(jié)美團(tuán)Android崗職能要求
這篇文章主要介紹了2021最新Android筆試題總結(jié)以及美團(tuán)Android崗職能要求,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08Android?studio實(shí)現(xiàn)動(dòng)態(tài)背景頁(yè)面
這篇文章主要為大家詳細(xì)介紹了Android?studio實(shí)現(xiàn)動(dòng)態(tài)背景頁(yè)面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Flutter時(shí)間軸Timeline的實(shí)現(xiàn)
時(shí)間軸在很多地方都可以用的到,本文介紹了Flutter時(shí)間軸Timeline的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05Android Camera是否支持變焦的判斷方法總結(jié)
這篇文章主要介紹了Android Camera是否支持變焦的判斷方法總結(jié),本文總結(jié)了調(diào)節(jié)攝像頭焦距編程中遇到的一些問(wèn)題和解決方法,需要的朋友可以參考下2015-04-04詳解flutter如何實(shí)現(xiàn)局部導(dǎo)航管理
這篇文章主要為大家介紹了詳解flutter如何實(shí)現(xiàn)局部導(dǎo)航管理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01