APP 完整性校验

  • Post author:
  • Post category:其他



在app开发完成发布后,难免会对app的安全性有所顾及,记录一下app完整性校验的机制来防止app被反编译造成后果。






完整性校验原理







所谓完整性校验就是我们用各种算法来计算一个文件的完整性,防止这个文件被修改。其中常用的方法就是计算一个文件的




CRC32


的值或者计算一个文件的哈希值。我们在防止


apk


被反编译的方法中也可以采用这种方法。我们知道


apk


生成的


classes.dex


主要由


java


文件生成的,它是整个


apk


的逻辑实现。所以我们可以对


classes.dex


文件进行完整性校验,来保证整个程序的逻辑不被修改。如果我们想要保证整个


apk


文件的完整性,也可以对整个


apk


文件进行完整性校验。下面我们分别来实现对


classes.dex


文件和


apk


文件的完整性校验。
















1.








用crc32对classes.dex文件的完整性进行校验














(1)可以打印出来我们的apk生的classes.dex文件的crc32的值,代码如下:















private void classesDexCheck() {
		String apkPath = getPackageCodePath();
		Long dexCrc = Long.parseLong(getString(R.string.classesdex_crc));
		try {
			ZipFile zipfile = new ZipFile(apkPath);
			ZipEntry dexentry = zipfile.getEntry("classes.dex");
			Log.i("verification", "classes.dexcrc=" + dexentry.getCrc());
			if (dexentry.getCrc() != dexCrc) {
				Log.i("verification", "Dexhas been modified!");
			} else {
				Log.i("verification", "Dex hasn't been modified!");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}



注意:R.string.classesdex_crc的值现在可以是个随机数。



(2)运行程序打印结果,我的apk程序的classes.dex的crc32的值为713769644



(3)将上面程序的classes.dex文件的crc32的值,保存在资源文件字符串中classesdex_crc中(当然也可以保存在服务器上,然后通过网络获取校验)【



个人觉得还是由服务端进行校验比较靠谱



】,然后再运行上面的apk程序,打印如下:



Dex hasn’t beenmodified!



(4)这时我们在上面的代码中随便加一行或者一个空格,然后重新编译运行会看到我们的程序的crc32的值改变了。程序打印如下:



Dex has beenmodified!









2.用哈希值对整个apk完整性进行校验







由于我们要对整个


apk


的完整性进行校验,所以我们的算出哈希值就不能存在资源文件中了因为


apk


中任何的改动都会引起最终


apk


生成的哈希值的不同。








(1)首先实现apk中计算自身哈希值的代码,如下:














private void apkShaCheck() {
		MessageDigest msgDigest = null;
		try {
			msgDigest = MessageDigest.getInstance("SHA-1");
			byte[] bytes = new byte[1024];
			int byteCount;
			String apkPath = getPackageCodePath();
			Log.i(TAG, "apkPath = " + apkPath);
			FileInputStream fis = new FileInputStream(new File(apkPath));
			while ((byteCount = fis.read(bytes)) > 0) {
				msgDigest.update(bytes, 0, byteCount);
			}
			BigInteger bi = new BigInteger(1, msgDigest.digest());
			String sha = bi.toString(16);
			Log.i(TAG, "apk sha = " + sha);
			fis.close();
			// 这里添加从服务器中获取哈希值然后进行对比校验
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


(2)用linux下的sha1sum命令计算我们的apk的哈希值,命令如下:


sha1sum verification.apk


(3)将(2)中生成的哈希值存到服务器上,然后在我们的代码中从服务器获取进行完整性比较






个人觉得通过服务端进行比较哈希值还是相对安全





上面我们用计算


crc32


和哈希值的方法分别对


classes.dex


文件和整个


apk


完整性进行了校验,当然两个校验方法也可以互换使用。根据上面的讲述相信大家对校验文件完整性的方法有了一定的了解,下一篇我们将讲解另一种


android apk


防止反编译技术,期待大家的捧场


链接:http://my.oschina.net/u/2323218/blog/406860