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);