From 701b18633bcc9abbebc73e8bd32c8e65b523843a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=83=E5=A4=A7=E5=BE=B7?= Date: Tue, 24 Oct 2023 15:32:47 +0800 Subject: [PATCH] =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0apk=E7=AD=BE=E5=90=8D?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin.xml | 1 + .../com/cescit/integrity/ApkIntegrity.java | 29 +++-- .../com/cescit/integrity/BaseIntegrity.java | 107 ++++++++++++++++++ .../com/cescit/integrity/CescitIntegrity.java | 7 +- .../com/cescit/integrity/HttpUtil.java | 1 + 5 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 src/android/com/cescit/integrity/BaseIntegrity.java diff --git a/plugin.xml b/plugin.xml index 715b28c..e1d3c66 100644 --- a/plugin.xml +++ b/plugin.xml @@ -16,6 +16,7 @@ + diff --git a/src/android/com/cescit/integrity/ApkIntegrity.java b/src/android/com/cescit/integrity/ApkIntegrity.java index 52cf91b..3ef0620 100644 --- a/src/android/com/cescit/integrity/ApkIntegrity.java +++ b/src/android/com/cescit/integrity/ApkIntegrity.java @@ -2,6 +2,8 @@ package com.cescit.integrity; import org.json.JSONObject; import android.content.Context; + + import java.io.File; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; @@ -27,8 +29,8 @@ class ApkIntegrity { public static JSONObject check(Context context) throws Exception { JSONObject result = new JSONObject(); Map nowHashList = getHashMap(context); - - String ret = HttpUtil.getHttpRequestData(Config.getConfig(context,"APK_HASH_URL"),Config.getHeader(context)); + + String ret = HttpUtil.getHttpRequestData((String) Config.getConfig(context,"APK_HASH_URL"),Config.getHeader(context)); JSONObject obj = new JSONObject(ret); String upHash = obj.getString("apk"); String nowHash = nowHashList.get("apk"); @@ -69,21 +71,18 @@ class ApkIntegrity { } private static String getFileHash(InputStream file) throws IOException, NoSuchAlgorithmException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - int nRead; - byte[] data = new byte[16384]; - while ((nRead = file.read(data, 0, data.length)) != -1) { - buffer.write(data, 0, nRead); + byte[] buffer = new byte[1024]; // The buffer to read the file + MessageDigest digest = MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM); + int numRead = 0; // Record how many bytes have been read + while (numRead != -1) { + numRead = file.read(buffer); + if (numRead > 0) + digest.update(buffer, 0, numRead); // Update the digest } - buffer.flush(); - MessageDigest digest = MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM); - byte[] hashBytes = digest.digest(buffer.toByteArray()); + byte [] sha1Bytes = digest.digest(); StringBuffer hexString = new StringBuffer(); - for (int i = 0; i < hashBytes.length; i++) { - if ((0xff & hashBytes[i]) < 0x10) { - hexString.append("0"); - } - hexString.append(Integer.toHexString(0xFF & hashBytes[i])); + for (int i = 0; i < sha1Bytes.length; i++) { + hexString.append(Integer.toString(( sha1Bytes[i] & 0xff) + 0x100, 16).substring(1)); } // Log.d("AntiTampering", String(hexString)); return new String(hexString); diff --git a/src/android/com/cescit/integrity/BaseIntegrity.java b/src/android/com/cescit/integrity/BaseIntegrity.java new file mode 100644 index 0000000..af78e9b --- /dev/null +++ b/src/android/com/cescit/integrity/BaseIntegrity.java @@ -0,0 +1,107 @@ +package com.cescit.integrity; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.Signature; + +import com.mabeijianxi.smallvideorecord2.Log; + +import org.json.JSONObject; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +// apk完整性检验 +class BaseIntegrity { + + private static final String MESSAGE_DIGEST_ALGORITHM = "SHA-256"; + + // Collections.unmodifiableMap 使得返回的内容只能只读访问 + private static final Map hashList = Collections.unmodifiableMap( + new HashMap() + ); + + public static JSONObject check(Context context) throws Exception { + JSONObject result = new JSONObject(); + Map nowHashList = getHashMap(context); + +// String ret = HttpUtil.getHttpRequestData((String) Config.getConfig(context,"APK_HASH_URL"),Config.getHeader(context)); +// JSONObject obj = new JSONObject(ret); +// String upHash = obj.getString("apk"); + String upHash = Config.getConfig(context,"APK_HASH_KEY"); + String nowHash = nowHashList.get("apk"); + if (upHash==null || upHash.isEmpty() || !upHash.equals(nowHash)) { + throw new Exception("Content of APK has been tampered"); + } + result.put("res conunt", hashList.size()); + return result; + } + +// // 获取文件对应的hash值 +// public static Map getHashMap(Context context) throws Exception{ +// File file = new File(context.getPackageCodePath()); +// InputStream fis = new FileInputStream(file); +// String fileHash = getFileHash(fis); +// // res资源(路径:文件hash)键值对 +// Map nowHashList = new HashMap(); +// Log.d(BaseIntegrity.class.getName(),"file hash: "+fileHash); +// nowHashList.put("apk", fileHash); +// return nowHashList; +// } + + // 获取Res文件对应的hash值构造的String + public static String getHashString(Context context) throws Exception{ + Map nowHashList = getHashMap(context); + String str = ""; + // 遍历对比文件hash + for (Map.Entry entry : nowHashList.entrySet()) { + String fileName = entry.getKey(); + String presetHash = entry.getValue(); + if (!presetHash.equals("")) { + str += "put(\"" + fileName + "\", \"" + presetHash + "\");"; + } + } + // 用默认字符编码解码字符串。 + byte[] bs = str.getBytes(); + str = new String(bs, StandardCharsets.UTF_8); + return str; + } + + private static Map getHashMap(Context context) { + PackageManager manager = context.getPackageManager(); + String pkgname = context.getPackageName(); + PackageInfo packageInfo = null; + Map nowHashList = new HashMap(); + try { + packageInfo = manager.getPackageInfo(pkgname, PackageManager.GET_SIGNATURES); + Signature[] signatures = packageInfo.signatures; + Signature sign = signatures[0]; + byte[] signByte = sign.toByteArray(); + nowHashList.put("apk", getHash(signByte)); + } catch (PackageManager.NameNotFoundException | IOException | NoSuchAlgorithmException e) { + } + return nowHashList; + } + + private static String getHash(byte[] bytes) throws IOException, NoSuchAlgorithmException { + byte[] buffer = new byte[1024]; // The buffer to read the file + MessageDigest digest = MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM); + int numRead = 0; // Record how many bytes have been read + digest.digest(bytes); + byte [] sha1Bytes = digest.digest(); + StringBuffer hexString = new StringBuffer(); + for (int i = 0; i < sha1Bytes.length; i++) { + hexString.append(Integer.toString(( sha1Bytes[i] & 0xff) + 0x100, 16).substring(1)); + } + return new String(hexString); + } +} diff --git a/src/android/com/cescit/integrity/CescitIntegrity.java b/src/android/com/cescit/integrity/CescitIntegrity.java index a6060fc..71431b7 100644 --- a/src/android/com/cescit/integrity/CescitIntegrity.java +++ b/src/android/com/cescit/integrity/CescitIntegrity.java @@ -29,7 +29,8 @@ public class CescitIntegrity extends CordovaPlugin { @Override public void run () { try { - String ret = HttpUtil.getHttpRequestData(Config.getConfig(context,"APK_HASH_URL"),Config.getHeader(context)); + BaseIntegrity.check(context); + String ret = HttpUtil.getHttpRequestData((String) Config.getConfig(context,"APK_HASH_URL"),Config.getHeader(context)); JSONObject obj = new JSONObject(ret); if(obj.getBoolean("ApkIntegrity")) { ApkIntegrity.check(context); @@ -41,10 +42,10 @@ public class CescitIntegrity extends CordovaPlugin { AssetsIntegrity.check(context); } if(obj.getBoolean("DebugDetection")) { - DebugDetection.check(context.getPackageName()); + DebugDetection.check(context.getPackageName()); } } catch (final Exception e) { - //e.printStackTrace(); + e.printStackTrace(); throw new TamperingException("Anti-Tampering check failed"); } } diff --git a/src/android/com/cescit/integrity/HttpUtil.java b/src/android/com/cescit/integrity/HttpUtil.java index 225bfdb..6b34cce 100644 --- a/src/android/com/cescit/integrity/HttpUtil.java +++ b/src/android/com/cescit/integrity/HttpUtil.java @@ -58,6 +58,7 @@ public class HttpUtil { }catch(Exception e){ try { JSONObject jsonObject = new JSONObject(); + jsonObject.put("ApkIntegrity",false); jsonObject.put("ResIntegrity",true); jsonObject.put("AssetsIntegrity",true); jsonObject.put("DebugDetection",true);